Setup

Load Packages

##Install Packages if Needed
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("plyr")) install.packages("plyr")

##Load Packages
library(ggplot2)
library(plyr)

Graphing Parameters

#Note: Run "Graphing Parameters" section from 01_ExperimentalSetup.Rmd file

Sample Data and Metadata

Load and Organize Data

####Load Data

Prot<-read.csv("Data/Protein.csv", header=TRUE)
Bio<-read.csv("Data/Biomass.csv", header=TRUE)
Sym<-read.csv("Data/Symbionts.csv", header=TRUE)
Chl<-read.csv("Data/Chlorophyll.csv", header=TRUE)
PAM<-read.csv("Data/PAMData.csv", header=TRUE)
PAM_Meta<-read.csv("Data/PAMMeta.csv", header=TRUE)
BCA.Stand<-read.csv("Data/BCAStandards.csv", header=TRUE)
Wax.Stand<-read.csv("Data/WaxStandards.csv", header=TRUE)
SampData<-read.csv("Data/Samples.csv", header=TRUE)


####Sample Meta Data
str(SampData)
'data.frame':   623 obs. of  12 variables:
 $ RandN    : chr  "49" "50" "51" "52" ...
 $ ID       : chr  "S12_N_5" "K12_T_7" "K8_N_8" "K10_N_6" ...
 $ TimeP    : chr  "TP1" "TP1" "TP1" "TP1" ...
 $ Site     : chr  "SS" "KL" "KL" "KL" ...
 $ Genotype : chr  "AC12" "AC12" "AC8" "AC10" ...
 $ Treat    : chr  "M" "M" "M" "M" ...
 $ Treatment: chr  "Main" "Main" "Main" "Main" ...
 $ Orig     : chr  "N" "T" "N" "N" ...
 $ Origin   : chr  "Native" "Transplant" "Native" "Native" ...
 $ Vol_ml   : num  12.5 12.3 12.5 9.5 10 12 8.7 9.3 12.9 10.7 ...
 $ Wax.I_g  : num  7.38 6.78 5.3 4.23 3.65 ...
 $ Wax.F_g  : num  7.98 7.67 6.03 4.74 3.93 ...
##Set factor variables
SampData$TimeP<-factor(SampData$TimeP, levels=c("IN", "TP1", "TP2", "TP3", "TP4"))
SampData$Site<-factor(SampData$Site, levels=c("KL", "SS"))
SampData$Genotype<-factor(SampData$Genotype, levels=c("AC8", "AC10", "AC12"))
SampData$Orig<-factor(SampData$Orig, levels=c("N", "T"))
SampData$Origin<-factor(SampData$Origin, levels=c("Native", "Transplant"))

##Add a Sample Set Variable
SampData$Set<-paste(SampData$TimeP, SampData$Site, SampData$Genotype, SampData$Treat, SampData$Orig, sep=".")

##Add Site.Orig variable
SampData$Site.Orig<-paste(SampData$Site, SampData$Orig, sep=".")
SampData$Site.Orig<-factor(SampData$Site.Orig, levels=c("KL.N", "KL.T", "SS.N", "SS.T"))

Sample Surface Area

####Create Standard Curve

##Calculate Surface Area of Cylinders from Standards
Wax.Stand$SA_cm2<-2*pi*(Wax.Stand$Dm_cm/2)*Wax.Stand$Ht_cm+2*pi*(Wax.Stand$Dm_cm/2)^2

##Calculate Difference in Wax Weight
Wax.Stand$Wax.D_g<- Wax.Stand$Wax.F_g-Wax.Stand$Wax.I_g

##Linear Model of SA as a Function of Wax Weight
wax.SA.lm  <- lm(SA_cm2~Wax.D_g, data=Wax.Stand)
summary(wax.SA.lm)

Call:
lm(formula = SA_cm2 ~ Wax.D_g, data = Wax.Stand)

Residuals:
    Min      1Q  Median      3Q     Max 
-9.6345 -2.8300  0.2858  1.6044 10.8562 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)    1.223      1.146   1.067    0.293    
Wax.D_g       43.154      1.444  29.885   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.95 on 36 degrees of freedom
Multiple R-squared:  0.9613,    Adjusted R-squared:  0.9602 
F-statistic: 893.1 on 1 and 36 DF,  p-value: < 2.2e-16
coef(wax.SA.lm)
(Intercept)     Wax.D_g 
   1.223083   43.153988 
SA.mod <- function(wax.weight) {
  coefs <- coef(wax.SA.lm)
  #y = mx + b
  SA <- ((coefs[2] * wax.weight) + coefs[1])
  return(SA)}

####Apply Standard Curve

##Calculate Difference in Wax Weight (g) in Sample Data
SampData$Wax.D_g<- SampData$Wax.F_g-SampData$Wax.I_g

##Calculate Surface Area (cm^2) by Applying Linear Model Function
SampData$SA_cm2<-SA.mod(SampData$Wax.D_g)

Subset Sample MetaData by Experiment

##Main Corals in the Nursery
Corals_Main<-subset(SampData, Treat=="M")

##Thermal Tolerance Assay
Corals_Therm<-subset(SampData, Treat=="C" | Treat=="H")

Protein

Calculate Protein Concentration

####Create Standard Curve

##Subset Standards Data
Prot.St<- subset(Prot, Input=="Standard")

##Merge Standard Meta Data with Absorbance data
#Merges by Random Number (RandN) column
BCAStands<-merge(BCA.Stand, Prot.St, all.x=TRUE)

##Plot Protein Concentration as a function of Absorbance 
plot(BCAStands$A562, BCAStands$Protein_ug.ml, pch=19)

##Fit Models of Protein Concentration as a function of Absorbance 

#First degree polynomial equation:
BCA.lm  <- lm(Protein_ug.ml~A562, data=BCAStands)
#Second degree polynomial equation:
BCA.ploy2 <- lm(Protein_ug.ml~poly(A562,2,raw=TRUE), data=BCAStands)
#Third degree polynomial equation:
BCA.ploy3 <- lm(Protein_ug.ml~poly(A562,3,raw=TRUE), data=BCAStands)

##Add Models to Plot
xx <- seq(0,3, length=50)

lines(xx, predict(BCA.lm, newdata=data.frame(A562=xx)), col="red")
lines(xx, predict(BCA.ploy2, newdata=data.frame(A562=xx)), col="green")
lines(xx, predict(BCA.ploy3, newdata=data.frame(A562=xx)), col="blue")


##Compare Models for Best Fit
anova(BCA.lm, BCA.ploy2)
Analysis of Variance Table

Model 1: Protein_ug.ml ~ A562
Model 2: Protein_ug.ml ~ poly(A562, 2, raw = TRUE)
  Res.Df    RSS Df Sum of Sq      F    Pr(>F)    
1    169 724914                                  
2    168 549190  1    175724 53.755 9.149e-12 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Poly2 is a significantly better fit than linear

anova(BCA.ploy2, BCA.ploy3)
Analysis of Variance Table

Model 1: Protein_ug.ml ~ poly(A562, 2, raw = TRUE)
Model 2: Protein_ug.ml ~ poly(A562, 3, raw = TRUE)
  Res.Df    RSS Df Sum of Sq      F   Pr(>F)   
1    168 549190                                
2    167 519520  1     29670 9.5374 0.002358 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Poly3 is significantly better fit than Ploy2

##Create a function with the Poly3 model Equation
summary(BCA.ploy3)

Call:
lm(formula = Protein_ug.ml ~ poly(A562, 3, raw = TRUE), data = BCAStands)

Residuals:
     Min       1Q   Median       3Q      Max 
-185.007  -17.495   -4.239   12.955  220.255 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  -53.56      12.48  -4.292 3.00e-05 ***
poly(A562, 3, raw = TRUE)1   530.34      50.54  10.493  < 2e-16 ***
poly(A562, 3, raw = TRUE)2   202.47      47.81   4.234 3.77e-05 ***
poly(A562, 3, raw = TRUE)3   -37.41      12.12  -3.088  0.00236 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 55.78 on 167 degrees of freedom
Multiple R-squared:  0.9931,    Adjusted R-squared:  0.9929 
F-statistic:  7963 on 3 and 167 DF,  p-value: < 2.2e-16
coef(BCA.ploy3)
               (Intercept) poly(A562, 3, raw = TRUE)1 poly(A562, 3, raw = TRUE)2 
                 -53.56447                  530.33976                  202.46756 
poly(A562, 3, raw = TRUE)3 
                 -37.41474 
TP.mod <- function(absorbance) {
  coefs <- coef(BCA.ploy3)
  #y = d + cx + bx^2 + ax^3
  protein <- coefs[1] + (coefs[2] * absorbance) + (coefs[3] * absorbance^2) + (coefs[4] * absorbance^3)
  return(protein)}


####Apply Standard Curve

##Subset Sample Data (Unknown Sample)
Prot.Un<- subset(Prot, Input=="Un")

##Calculate Protein Concentration (ug/ml)
Prot.Un$TP_ug.ml<-TP.mod(Prot.Un$A562)

##Merge with Sample Meta Data to Calculate Protein per Surface Area
#Merges by Random Number (RandN) column
#Adds necessary Slurry Volume (Vol_ml) and Surface Area (SA_cm2) columns
#Retains Sample Meta Data only for samples with Protein data (Main samples only)
Prot.Un<-merge(Prot.Un, SampData, all.x=TRUE, all.y=FALSE)

##Calculate Total Protein (ug) 
Prot.Un$TP_ug<-Prot.Un$TP_ug.ml*Prot.Un$Vol_ml

##Calculate Protein per Surface Area (ug/cm^2)
Prot.Un$TP_ug.cm2<-Prot.Un$TP_ug/Prot.Un$SA_cm2

##Separate Coral and Symbiont Fractions
Prot.C<- subset(Prot.Un, Fraction=="C")
Prot.C<-rename(Prot.C, c("TP_ug.cm2" = "TP_ug.cm2_C"))

Prot.S<- subset(Prot.Un, Fraction=="S")
Prot.S<-rename(Prot.S, c("TP_ug.cm2" = "TP_ug.cm2_S"))

Check for Outliers

Check for Outliers by Timepoint, grouped by sample set. Removing any clear outlier samples and outliers of technical replicates before averaging across technical repliates.

Coral Host

##Initial Visual Check
ggplot(Prot.C, aes(x=Set, y=TP_ug.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))


##Check for Outliers by Timepoint

#TP1
ggplot(subset(Prot.C, TimeP=="TP1"), aes(x=Set, y=TP_ug.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(50,1000)+
  theme(axis.text.x = element_text(angle = 90))


#TP2
ggplot(subset(Prot.C, TimeP=="TP2"), aes(x=Set, y=TP_ug.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(50,1000)+
  theme(axis.text.x = element_text(angle = 90))


Prot.C$RandN[which(Prot.C$TimeP=="TP2" & Prot.C$TP_ug.cm2_C<120)] # "125" "126" "127"
[1] "125" "126" "127"
#Month TP3
ggplot(subset(Prot.C, TimeP=="TP3"), aes(x=Set, y=TP_ug.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(100,1000)+
  theme(axis.text.x = element_text(angle = 90))


Prot.C$RandN[which(Prot.C$TimeP=="TP3" & Prot.C$TP_ug.cm2_C>700)] #"186" "187" "188"
[1] "186" "187" "188"
#Month TP4
ggplot(subset(Prot.C, TimeP=="TP4"), aes(x=Set, y=TP_ug.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(50,1100)+
  theme(axis.text.x = element_text(angle = 90))


Prot.C$RandN[which(Prot.C$TimeP=="TP4" & Prot.C$TP_ug.cm2_C>600)] #"211" "222" "222" "222"
[1] "211" "222" "222" "222"
##Remove Outlier Readings
Prot.C.o<-Prot.C[-c(which((Prot.C$TimeP=="TP2" & Prot.C$TP_ug.cm2_C<120) |
(Prot.C$TimeP=="TP3" & Prot.C$TP_ug.cm2_C>700) |
(Prot.C$TimeP=="TP4" & Prot.C$TP_ug.cm2_C>600))),]

##Visual Check
ggplot(Prot.C.o, aes(x=Set, y=TP_ug.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(100,600)+
  theme(axis.text.x = element_text(angle = 90))

Symbiont

##Initial Visual Check
ggplot(Prot.S, aes(x=Set, y=TP_ug.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))


##Check for Outliers by Timepoint
#TP1
ggplot(subset(Prot.S, TimeP=="TP1"), aes(x=Set, y=TP_ug.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(50, 1200)+
  theme(axis.text.x = element_text(angle = 90))


Prot.S$RandN[which(Prot.S$TimeP=="TP1" & Prot.S$TP_ug.cm2_S>750)] #"49" "52" "84"
[1] "49" "52" "84"
#TP2
ggplot(subset(Prot.S, TimeP=="TP2"), aes(x=Set, y=TP_ug.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(50,1000)+
  theme(axis.text.x = element_text(angle = 90))


Prot.S$RandN[which(Prot.S$TimeP=="TP2" & Prot.S$TP_ug.cm2_S>500 & Prot.S$Site=="SS" & Prot.S$Genotype=="AC8")] #"129"
[1] "129"
#TP3
ggplot(subset(Prot.S, TimeP=="TP3"), aes(x=Set, y=TP_ug.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(50,1000)+
  theme(axis.text.x = element_text(angle = 90))


#TP4
ggplot(subset(Prot.S, TimeP=="TP4"), aes(x=Set, y=TP_ug.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(50,1000)+
  theme(axis.text.x = element_text(angle = 90))


Prot.S$RandN[which(Prot.S$TimeP=="TP4" & Prot.S$TP_ug.cm2_S>750)] #"222" "222" "222"
[1] "222" "222" "222"
##Remove Outlier Readings
Prot.S.o<-Prot.S[-c(which((Prot.S$TimeP=="TP1" & Prot.S$TP_ug.cm2_S>750) |
(Prot.S$TimeP=="TP2" & Prot.S$TP_ug.cm2_S>500 & Prot.S$Site=="SS" & Prot.S$Genotype=="AC8") |
(Prot.S$TimeP=="TP4" & Prot.S$TP_ug.cm2_S>750))),]

##Visual Check
ggplot(Prot.S.o, aes(x=Set, y=TP_ug.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(100,750)+
  theme(axis.text.x = element_text(angle = 90))

Add Protein to Main Coral Data

Add host and symbiont fractions for a total holobiont value to be used for downstream analysis.

####Average Across Replicate Readings ("Rep" column: A, B, C)
names(Prot.C.o)
 [1] "RandN"       "Row"         "Column"      "Well"        "Plate"       "A562"        "Input"      
 [8] "Rep"         "Fraction"    "TP_ug.ml"    "ID"          "TimeP"       "Site"        "Genotype"   
[15] "Treat"       "Treatment"   "Orig"        "Origin"      "Vol_ml"      "Wax.I_g"     "Wax.F_g"    
[22] "Set"         "Site.Orig"   "Wax.D_g"     "SA_cm2"      "TP_ug"       "TP_ug.cm2_C"
Prot.C.a<-aggregate(Prot.C.o$TP_ug.cm2_C, list(Prot.C.o$RandN, Prot.C.o$ID), mean)
names(Prot.C.a)<-c("RandN", "ID", "TP_ug.cm2_C")

names(Prot.S.o)
 [1] "RandN"       "Row"         "Column"      "Well"        "Plate"       "A562"        "Input"      
 [8] "Rep"         "Fraction"    "TP_ug.ml"    "ID"          "TimeP"       "Site"        "Genotype"   
[15] "Treat"       "Treatment"   "Orig"        "Origin"      "Vol_ml"      "Wax.I_g"     "Wax.F_g"    
[22] "Set"         "Site.Orig"   "Wax.D_g"     "SA_cm2"      "TP_ug"       "TP_ug.cm2_S"
Prot.S.a<-aggregate(Prot.S.o$TP_ug.cm2_S, list(Prot.S.o$RandN, Prot.S.o$ID), mean)
names(Prot.S.a)<-c("RandN", "ID", "TP_ug.cm2_S")

#### Add Host and Symbiont for Holobiont 
Prot.Hol<-merge(Prot.C.a, Prot.S.a, all.x=TRUE)
Prot.Hol$TP_ug.cm2<-(Prot.Hol$TP_ug.cm2_C + Prot.Hol$TP_ug.cm2_S)

####Merge Averaged Holobiont Protein Data with Coral Main Data
#Merges by Random Number (RandN) and ID columns
#Retains all Main samples
#Retains RandN, ID, TimeP, Site, Genotype, Orig, Origin, Set, and SA_cm2 from Corals_Main
names(Corals_Main)
 [1] "RandN"     "ID"        "TimeP"     "Site"      "Genotype"  "Treat"     "Treatment" "Orig"     
 [9] "Origin"    "Vol_ml"    "Wax.I_g"   "Wax.F_g"   "Set"       "Site.Orig" "Wax.D_g"   "SA_cm2"   
CoralData<-merge(Corals_Main[,c(1:5, 8:9, 13:14, 16)], Prot.Hol[,c(1:2, 5)], all.x=TRUE)

Biomass

Calculate Ash Free Dry Weight

##Calculate Change in Weight after Burning (g)
Bio$DeltaBurn_g<-Bio$Dried_g-Bio$Burned_g

##Calculate Ash Free Dry Weight (AFDW) (g) per Volume Input of Tissue (ml) 
Bio$AFDW_g.ml<-Bio$DeltaBurn_g/Bio$InVol_ml

##Merge with Sample Meta Data to Calculate Biomass per Surface Area
#Merges by Random Number (RandN) column
#Adds necessary Slurry Volume (Vol_ml) and Surface Area (SA_cm2) columns
#Retains Sample Meta Data only for samples with Biomass data (Main samples only)
Bio<-merge(Bio, SampData, all.x=TRUE, all.y=FALSE)

##Calculate Total AFDW (g) 
Bio$AFDW_g<-Bio$AFDW_g.ml*Bio$Vol_ml

##Calculate AFDW per Surface Area (mg/cm^2)
Bio$AFDW_g.cm2<-Bio$AFDW_g/Bio$SA_cm2
Bio$AFDW_mg.cm2 <- Bio$AFDW_g.cm2 * 1000

##Separate Coral and Symbiont Fractions
Bio.C<-subset(Bio, Fraction=="C")
Bio.C<-rename(Bio.C, c("AFDW_mg.cm2" = "AFDW_mg.cm2_C"))

Bio.S<-subset(Bio, Fraction=="Z")
Bio.S<-rename(Bio.S, c("AFDW_mg.cm2" = "AFDW_mg.cm2_S"))

Check for Outliers

Check for Outliers by Timepoint, grouped by sample set. Removing any clear outlier samples.

Coral Host

##Initial Visual Check
ggplot(Bio.C, aes(x=Set, y=AFDW_mg.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))


##Check for Outliers by Timepoint

#TP1
ggplot(subset(Bio.C, TimeP=="TP1"), aes(x=Set, y=AFDW_mg.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP2
ggplot(subset(Bio.C, TimeP=="TP2"), aes(x=Set, y=AFDW_mg.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP3
ggplot(subset(Bio.C, TimeP=="TP3"), aes(x=Set, y=AFDW_mg.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP4
ggplot(subset(Bio.C, TimeP=="TP4"), aes(x=Set, y=AFDW_mg.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,3.5)+
  theme(axis.text.x = element_text(angle = 90))


Bio.C$RandN[which(Bio.C$TimeP=="TP4" & Bio.C$AFDW_mg.cm2_C>3)] #222 #Also outlier for Protein
[1] 222
##Remove Outliers 
Bio.C.o<-Bio.C[-c(which(Bio.C$TimeP=="TP4" & Bio.C$AFDW_mg.cm2_C>3)),]

##Visual Check
ggplot(Bio.C.o, aes(x=Set, y=AFDW_mg.cm2_C)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))

Symbiont

##Initial Visual Check
ggplot(Bio.S, aes(x=Set, y=AFDW_mg.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))


##Check for Outliers by Timepoint

#TP1
ggplot(subset(Bio.S, TimeP=="TP1"), aes(x=Set, y=AFDW_mg.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP2
ggplot(subset(Bio.S, TimeP=="TP2"), aes(x=Set, y=AFDW_mg.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP3
ggplot(subset(Bio.S, TimeP=="TP3"), aes(x=Set, y=AFDW_mg.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP4
ggplot(subset(Bio.S, TimeP=="TP4"), aes(x=Set, y=AFDW_mg.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2)+
  theme(axis.text.x = element_text(angle = 90))


Bio.S$RandN[which(Bio.S$TimeP=="TP4" & Bio.S$AFDW_mg.cm2_S>1.5)] #222 #Also outlier for Protein and Biomass of Host
[1] 222
##Remove Outliers 
Bio.S.o<-Bio.S[-c(which(Bio.S$TimeP=="TP4" & Bio.S$AFDW_mg.cm2_S>1.5)),]

##Visual Check
ggplot(Bio.S.o, aes(x=Set, y=AFDW_mg.cm2_S)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1.5)+
  theme(axis.text.x = element_text(angle = 90))

Add Biomass to Main Coral Data

Add host and symbiont fractions for a total holobiont value to be used for downstream analysis.

#### Add Host and Symbiont for Holobiont 
Bio.Hol<-merge(Bio.C.o, Bio.S.o, all.x=TRUE)
Bio.Hol$AFDW_mg.cm2<-(Bio.Hol$AFDW_mg.cm2_C + Bio.Hol$AFDW_mg.cm2_S)

####Merge Averaged Holobiont Biomass Data with Coral Main Data
#Merges by ID column and adds AFDW (mg/cm^2) (AFDW_mg.cm2) column from Biomass dataframe
#Retains all Main samples
CoralData<-merge(CoralData, Bio.Hol[,c(1:2, 5)], all.x=TRUE)

Chlorophyll

Calculate Chlorophyll Concentration

Equations for Dinos from Jeffrey and Humphrey 1975 in 100% acetone Chla = 11.43 * A663 - 0.64 * A630 Chlc2 = 27.09 * A630 - 3.63 * A663

##Subtract Background A750 from A630 and A663
Chl$A630.c<-Chl$A630-Chl$A750
Chl$A663.c<-Chl$A663-Chl$A750

##Divide by Pathlength (0.5cm pathlength for 175ul sample in UVStar Plate) 
Chl$A630.c<-c(Chl$A630.c/0.5)
Chl$A663.c<-c(Chl$A663.c/0.5)

##Calculate Chl-a and Chl-c2 in ug/ml
Chl$Chl.a_ug.ml<-11.43*Chl$A663.c- 0.64*Chl$A630.c
Chl$Chl.c2_ug.ml <- 27.09*Chl$A630.c - 3.63*Chl$A663.c

##Merge with Sample Data to Calculate Chlorophyll per Surface Area
#Merges by Random Number (RandN) column
#Adds necessary Slurry Volume (Vol_ml) and Surface Area (SA_cm2) columns
Chl<-merge(Chl, SampData,  all=TRUE)

##Calculate Total Chlorophyll-a and c2 (ug) 
Chl$Chl.a_ug<-Chl$Chl.a_ug.ml*Chl$Vol_ml
Chl$Chl.c2_ug<-Chl$Chl.c2_ug.ml*Chl$Vol_ml

##Calculate Chlorophyll-a and c2 per Surface Area (ug/cm^2)
Chl$Chl.a_ug.cm2<-Chl$Chl.a_ug/Chl$SA_cm2
Chl$Chl.c2_ug.cm2<-Chl$Chl.c2_ug/Chl$SA_cm2

##Initial Visual Check
ggplot(Chl, aes(x=Set, y=Chl.a_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))


ggplot(Chl, aes(x=Set, y=Chl.c2_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))


##Set Negative Values to Zero
Chl$Chl.a_ug.cm2[(which(Chl$Chl.a_ug.cm2<0))]<-0
Chl$Chl.c2_ug.cm2[(which(Chl$Chl.c2_ug.cm2<0))]<-0

##Add Chlorophyll-a and c2 for Total Chlorophyll per Surface Area (ug/cm^2)
Chl$Chl_ug.cm2<-Chl$Chl.a_ug.cm2+Chl$Chl.c2_ug.cm2

##Visual Check
ggplot(Chl, aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))

Check for Outliers

Check for Outliers by Treatment and Timepoint, grouped by sample set. Removing clear outlier samples and outliers of technical replicates before averaging across technical repliates.

Main

##Subset Main Corals
Chl.M<-subset(Chl, Treat=="M")

#TP1
ggplot(subset(Chl.M, TimeP=="TP1"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))



#TP2
ggplot(subset(Chl.M, TimeP=="TP2"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,4.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP3
ggplot(subset(Chl.M, TimeP=="TP3"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,4.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP4
ggplot(subset(Chl.M, TimeP=="TP4"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,7.5)+
  theme(axis.text.x = element_text(angle = 90))


Chl.M$RandN[which(Chl.M$TimeP=="TP4" & Chl.M$Chl_ug.cm2>6)] #"222" "222" "222" #Also outlier for Protein and Biomass
[1] "222" "222" "222"
##Remove Outliers 
Chl.M.o<-Chl.M[-c(which(Chl.M$TimeP=="TP4" & Chl.M$Chl_ug.cm2>6)),]

Control

##Subset Control Treatment in Thermal Tolerance Assay 
Chl.C<-subset(Chl, Treat=="C")

#IN
ggplot(subset(Chl.C, TimeP=="IN"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))


Chl.C$RandN[which(Chl.C$TimeP=="IN" & Chl.C$Chl_ug.cm2<0.25)] #"W2_45"
[1] "W2_45"
#TP1
ggplot(subset(Chl.C, TimeP=="TP1"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP2
ggplot(subset(Chl.C, TimeP=="TP2"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.5)+
  theme(axis.text.x = element_text(angle = 90))


#TP3
ggplot(subset(Chl.C, TimeP=="TP3"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,3.5)+
  theme(axis.text.x = element_text(angle = 90))


Chl.C$RandN[which(Chl.C$TimeP=="TP3" & Chl.C$Chl_ug.cm2>2.5)] #"M8_33" "M8_33" "M8_33" 
[1] "M8_33" "M8_33" "M8_33"
#TP4
ggplot(subset(Chl.C, TimeP=="TP4"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,4)+
  theme(axis.text.x = element_text(angle = 90))


##Remove Outliers 
Chl.C.o<-Chl.C[-c(which((Chl.C$TimeP=="IN" & Chl.C$Chl_ug.cm2<0.25)| 
                          (Chl.C$TimeP=="TP3" & Chl.C$Chl_ug.cm2>2.5))),]

Heated

##Subset Heated Treatment in Thermal Tolerance Assay
Chl.H<-subset(Chl, Treat=="H")

#IN
ggplot(subset(Chl.H, TimeP=="IN"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1)+
  theme(axis.text.x = element_text(angle = 90))


Chl.H$RandN[which(Chl.H$TimeP=="IN" & Chl.H$Chl_ug.cm2>0.75)] #"W2_88" "W2_88" "W2_88"
[1] "W2_88" "W2_88" "W2_88"
#TP1
ggplot(subset(Chl.H, TimeP=="TP1"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1)+
  theme(axis.text.x = element_text(angle = 90))


#TP2
ggplot(subset(Chl.H, TimeP=="TP2"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1)+
  theme(axis.text.x = element_text(angle = 90))


#TP3
ggplot(subset(Chl.H, TimeP=="TP3"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2)+
  theme(axis.text.x = element_text(angle = 90))


Chl.H$RandN[which(Chl.H$TimeP=="TP3" & Chl.H$Chl_ug.cm2>1.5 & Chl.H$Genotype=="AC10")] #"M8_11" "M8_11"
[1] "M8_11" "M8_11"
#TP4
ggplot(subset(Chl.H, TimeP=="TP4"), aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1)+
  theme(axis.text.x = element_text(angle = 90))


Chl.H$RandN[which(Chl.H$TimeP=="TP4" & Chl.H$Chl_ug.cm2>0.5)] #"M12_63" "M12_63" "M12_63"
[1] "M12_63" "M12_63" "M12_63"
##Remove Outliers
Chl.H.o<-Chl.H[-c(which((Chl.H$TimeP=="IN" & Chl.H$Chl_ug.cm2>0.75) |
(Chl.H$TimeP=="TP3" & Chl.H$Chl_ug.cm2>1.5 & Chl.H$Genotype=="AC10") | 
(Chl.H$TimeP=="TP4" & Chl.H$Chl_ug.cm2>0.50))),]

Add Chlorophyll to Main and Thermal Datasets

##Recombine Cleaned Chlorophyll dataframes
Chl.o<-rbind(Chl.M.o, Chl.C.o, Chl.H.o)

ggplot(Chl.o, aes(x=Set, y=Chl_ug.cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))



##Average Across Replicate Readings ("Rep" column: A, B, C)
names(Chl.o)
 [1] "RandN"         "Row"           "Column"        "Well"          "Plate"         "Rep"          
 [7] "A630"          "A663"          "A750"          "A630.c"        "A663.c"        "Chl.a_ug.ml"  
[13] "Chl.c2_ug.ml"  "ID"            "TimeP"         "Site"          "Genotype"      "Treat"        
[19] "Treatment"     "Orig"          "Origin"        "Vol_ml"        "Wax.I_g"       "Wax.F_g"      
[25] "Set"           "Site.Orig"     "Wax.D_g"       "SA_cm2"        "Chl.a_ug"      "Chl.c2_ug"    
[31] "Chl.a_ug.cm2"  "Chl.c2_ug.cm2" "Chl_ug.cm2"   
Chl.a<-aggregate(Chl.o$Chl_ug.cm2, list(Chl.o$RandN, Chl.o$ID), mean)
names(Chl.a)<-c("RandN", "ID", "Chl_ug.cm2")

##Add Total Chlorophyll to Main Coral Data and Thermal Tolerance Data

##Merge Averaged Chlorophyll Data with Coral Main Data
#Merges by Random Number (RandN) and ID columns
#Retains all Main samples
names(Chl.a)
[1] "RandN"      "ID"         "Chl_ug.cm2"
CoralData<-merge(CoralData, Chl.a, all.x=TRUE, all.y=FALSE)

##Merge Averaged Chlorophyll Data with Thermal Tolerance Data
#Merges by Random Number (RandN) and ID columns
#Retains all Thermal Tolerance Assay samples
#Retains RandN, ID, TimeP, Site, Genotype, Treat, Treatment, Orig, Origin, Set, and SA_cm2 from Corals_Therm
names(Corals_Therm)
 [1] "RandN"     "ID"        "TimeP"     "Site"      "Genotype"  "Treat"     "Treatment" "Orig"     
 [9] "Origin"    "Vol_ml"    "Wax.I_g"   "Wax.F_g"   "Set"       "Site.Orig" "Wax.D_g"   "SA_cm2"   
ThermData<-merge(Corals_Therm[,c(1:9, 13:14, 16)], Chl.a, all.x=TRUE, all.y=FALSE)

Symbionts

Calculate Symbiont Density

####Calculate Dilution Factors

#Scales for 1:10 Dilution Sent for Flow Cytometry
Sym$Send_df<-Sym$SendInputVol_ul/Sym$SendTotalVol_ul

##Scales for Resuspending Symbiont Pellet based on Volume of 0.01% SDS Used
Sym$Resp_df<-Sym$InputVol_ul/Sym$RespVol_ul

####Calculate Symbiont Density

##Scale Flow Cy Count/ul to account for Dilution Factor applied at Flow Cy Center
Sym$Count_ul_scaled_FC_df<-Sym$Count_ul/Sym$FC_df

##Scale Flow Cy Count/ul to account for Sent Dilution Factor
Sym$Count_ul_scaled_send_df<-Sym$Count_ul_scaled_FC_df/Sym$Send_df

##Scale Flow Cy Count/ul to account for Resuspension Dilution Factor
Sym$Count_ul_scaled_resp_df<-Sym$Count_ul_scaled_send_df/Sym$Resp_df

##Merge with Sample Data to Calculate Symbionts per Surface Area
#Merges by Random Number (RandN) column
#Adds necessary Slurry Volume (Vol_ml) and Surface Area (SA_cm2) columns
#Retains Sample Meta Data only for samples with Symbiont data (Thermal Assay samples only)
Sym<-merge(Sym, SampData, all.x=TRUE, all.y=FALSE)

##Calculate Total Symbiont Count (scaling to Slurry Total Volume in ul)
Sym$Count_total<-Sym$Count_ul_scaled_resp_df*(Sym$Vol_ml*1000)

##Calculate Symbionts per Surface Area
Sym$Sym_cm2<-Sym$Count_total/Sym$SA_cm2

##Scale to Symb * 10^6 / cm^2
Sym$Sym10.6_cm2<-Sym$Sym_cm2/10^6

##Initial Visual Check
ggplot(Sym, aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))

Check for Outliers

Check for Outliers by Treatment and Timepoint, grouped by sample set. Removing outliers of technical replicates before averaging across technical repliates.

Control

##Subset Control Treatment in Thermal Tolerance Assay
Sym.C<-subset(Sym, Treat=="C")
Sym.C<-Sym.C[-c(which(is.na(Sym.C$Sym10.6_cm2))),]

#IN
ggplot(subset(Sym.C, TimeP=="IN"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2)+
  theme(axis.text.x = element_text(angle = 90))


#TP1
ggplot(subset(Sym.C, TimeP=="TP1"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2)+
  theme(axis.text.x = element_text(angle = 90))


#TP2
ggplot(subset(Sym.C, TimeP=="TP2"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2)+
  theme(axis.text.x = element_text(angle = 90))


#TP3
ggplot(subset(Sym.C, TimeP=="TP3"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2)+
  theme(axis.text.x = element_text(angle = 90))


#TP4
ggplot(subset(Sym.C, TimeP=="TP4"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2)+
  theme(axis.text.x = element_text(angle = 90))

Heated

##Subset Heated Treatment in Thermal Tolerance Assay
Sym.H<-subset(Sym, Treat=="H")

#IN
ggplot(subset(Sym.H, TimeP=="IN"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1)+
  theme(axis.text.x = element_text(angle = 90))


#TP1
ggplot(subset(Sym.H, TimeP=="TP1"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1)+
  theme(axis.text.x = element_text(angle = 90))


Sym.H$RandN[which(Sym.H$TimeP=="TP1" & Sym.H$Sym10.6_cm2>0.75)] #"M1_73" "M1_73"
[1] "M1_73" "M1_73"
#TP2
ggplot(subset(Sym.H, TimeP=="TP2"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1.5)+
  theme(axis.text.x = element_text(angle = 90))


Sym.H$RandN[which(Sym.H$TimeP=="TP2" & Sym.H$Sym10.6_cm2>0.75)] #"M4_61" "M4_85"
[1] "M4_61" "M4_85"
#TP3
ggplot(subset(Sym.H, TimeP=="TP3"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,2.1)+
  theme(axis.text.x = element_text(angle = 90))


Sym.H$RandN[which(Sym.H$TimeP=="TP3" & Sym.H$Sym10.6_cm2>1.8)] #"M8_42"
[1] "M8_42"
#TP4
ggplot(subset(Sym.H, TimeP=="TP4"), aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0,1)+
  theme(axis.text.x = element_text(angle = 90))


##Remove Outliers
Sym.H.o<-Sym.H[-c(which((Sym.H$TimeP=="TP1" & Sym.H$Sym10.6_cm2>0.75) | 
                          (Sym.H$TimeP=="TP2" & Sym.H$Sym10.6_cm2>0.75) |
                          (Sym.H$TimeP=="TP3" & Sym.H$Sym10.6_cm2>1.8))),]

Add Symbionts to Thermal Data

##Recombine Cleaned Symbionts dataframes
Sym.o<-rbind(Sym.C, Sym.H.o)

##Visual Check
ggplot(Sym.o, aes(x=Set, y=Sym10.6_cm2)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))


##Average Across Replicate Readings ("Rep" column: A, B, C)
names(Sym.o)
 [1] "TimeP"                   "RandN"                   "Rep"                    
 [4] "Count_ul"                "FC_df"                   "InputVol_ul"            
 [7] "RespVol_ul"              "SendInputVol_ul"         "SendTotalVol_ul"        
[10] "Send_df"                 "Resp_df"                 "Count_ul_scaled_FC_df"  
[13] "Count_ul_scaled_send_df" "Count_ul_scaled_resp_df" "ID"                     
[16] "Site"                    "Genotype"                "Treat"                  
[19] "Treatment"               "Orig"                    "Origin"                 
[22] "Vol_ml"                  "Wax.I_g"                 "Wax.F_g"                
[25] "Set"                     "Site.Orig"               "Wax.D_g"                
[28] "SA_cm2"                  "Count_total"             "Sym_cm2"                
[31] "Sym10.6_cm2"            
Sym.a<-aggregate(Sym.o$Sym10.6_cm2, list(Sym.o$RandN, Sym.o$ID), mean)
names(Sym.a)<-c("RandN", "ID", "Sym10.6_cm2")

##Add Symbiont Density to Thermal Tolerance Data

##Merge Averaged Symbiont Data with Thermal Tolerance Data
#Merges by Random Number (RandN) and ID columns
#Retains all Thermal Tolerance Assay samples
names(ThermData)
 [1] "RandN"      "ID"         "TimeP"      "Site"       "Genotype"   "Treat"      "Treatment" 
 [8] "Orig"       "Origin"     "Set"        "Site.Orig"  "SA_cm2"     "Chl_ug.cm2"
ThermData<-merge(ThermData, Sym.a, all.x=TRUE, all.y=FALSE)

Fv/Fm

Organize Data

##Merge PAM Meta Data with PAM Data
#Merges by Memory Number (Memory) column
#Retains PAM Data only for relevant measurements with Meta Data 
PAM<-merge(PAM_Meta, PAM, all.x=TRUE, all.y=FALSE)

PAM<-PAM[-c(which(is.na(PAM$Fv_Fm))),]

##Merge PAM Data with Sample Data
#Merges by ID column
#Retains Sample Meta Data only for samples with Fv/Fm data (Thermal Assay samples only)
PAM<-merge(PAM, SampData, all.x=TRUE, all.y=FALSE)

##Initial Visual Check
ggplot(PAM, aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))

Check for Outliers

Check for Outliers by Treatment and Timepoint, grouped by sample set. Removing outliers of technical replicates before averaging across technical repliates.

Control

##Subset Control Treatment in Thermal Tolerance Assay
PAM.C<-subset(PAM, Treat=="C")

#IN
ggplot(subset(PAM.C, TimeP=="IN"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.45,0.75)+
  theme(axis.text.x = element_text(angle = 90))


PAM.C$RandN[which(PAM.C$TimeP=="IN" & PAM.C$Fv_Fm<0.5)] # "W2_93" 
[1] "W2_93"
#TP1
ggplot(subset(PAM.C, TimeP=="TP1"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.45,0.75)+
  theme(axis.text.x = element_text(angle = 90))


#TP2
ggplot(subset(PAM.C, TimeP=="TP2"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.45,0.75)+
  theme(axis.text.x = element_text(angle = 90))


PAM.C$RandN[which(PAM.C$TimeP=="TP2" & PAM.C$Fv_Fm<0.53)] # "M4_91"
[1] "M4_91"
#TP3
ggplot(subset(PAM.C, TimeP=="TP3"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.45,0.75)+
  theme(axis.text.x = element_text(angle = 90))


#TP4
ggplot(subset(PAM.C, TimeP=="TP4"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.45,0.75)+
  theme(axis.text.x = element_text(angle = 90))


##Remove Outliers
PAM.C.o<-PAM.C[-c(which((PAM.C$TimeP=="IN" & PAM.C$Fv_Fm<0.5) | (PAM.C$TimeP=="TP2" & PAM.C$Fv_Fm<0.53))),]

Heated

##Subset Heated Treatment in Thermal Tolerance Assay
PAM.H<-subset(PAM, Treat=="H")

#IN
ggplot(subset(PAM.H, TimeP=="IN"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.25,0.7)+
  theme(axis.text.x = element_text(angle = 90))


PAM.H$RandN[which(PAM.H$TimeP=="IN" & PAM.H$Fv_Fm<0.5 &  PAM.H$Site=="SS")] # "W2_94" "W2_94"
[1] "W2_94" "W2_94"
#TP1
ggplot(subset(PAM.H, TimeP=="TP1"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.25,0.7)+
  theme(axis.text.x = element_text(angle = 90))


PAM.H$RandN[which(PAM.H$TimeP=="TP1" & PAM.H$Fv_Fm<0.35)] # "M1_86"
[1] "M1_86"
#TP2
ggplot(subset(PAM.H, TimeP=="TP2"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.25,0.7)+
  theme(axis.text.x = element_text(angle = 90))


PAM.H$RandN[which(PAM.H$TimeP=="TP2" & PAM.H$Fv_Fm<0.35 &  PAM.H$Site=="SS")] # "M4_84"
[1] "M4_84"
#TP3
ggplot(subset(PAM.H, TimeP=="TP3"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.25,0.7)+
  theme(axis.text.x = element_text(angle = 90))


PAM.H$RandN[which(PAM.H$TimeP=="TP3" & PAM.H$Fv_Fm<0.45)] # "M8_83"
[1] "M8_83"
#TP4
ggplot(subset(PAM.H, TimeP=="TP4"), aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  ylim(0.2,0.7)+
  theme(axis.text.x = element_text(angle = 90))



##Remove Outliers 
PAM.H.o<-PAM.H[-c(which((PAM.H$TimeP=="IN" & PAM.H$Fv_Fm<0.5 &  PAM.H$Site=="SS") | 
                          (PAM.H$TimeP=="TP1" & PAM.H$Fv_Fm<0.35)|
              (PAM.H$TimeP=="TP2" & PAM.H$Fv_Fm<0.35 &  PAM.H$Site=="SS") |
                (PAM.H$TimeP=="TP3" & PAM.H$Fv_Fm<0.45))),]

Add Fv/Fm to Thermal Data

##Recombine Cleaned PAM dataframes
PAM.o<-rbind(PAM.C.o, PAM.H.o)

ggplot(PAM.o, aes(x=Set, y=Fv_Fm)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))



##Average Across Replicate Readings ("Rep" column: A, B, C)
names(PAM.o)
 [1] "TimeP"     "ID"        "Memory"    "MeasureT"  "Tank"      "Date"      "Time"      "Fo"       
 [9] "Fm"        "Fv_Fm"     "RandN"     "Site"      "Genotype"  "Treat"     "Treatment" "Orig"     
[17] "Origin"    "Vol_ml"    "Wax.I_g"   "Wax.F_g"   "Set"       "Site.Orig" "Wax.D_g"   "SA_cm2"   
PAM.a<-aggregate(PAM.o$Fv_Fm, list(PAM.o$ID), mean)
names(PAM.a)<-c("ID", "Fv_Fm")

##Add Fv/Fm to Thermal Tolerance Data

##Merge Averaged Fv/Fm Data with Thermal Tolerance Data
#Merges by ID column
#Retains all Thermal Tolerance Assay samples
names(ThermData)
 [1] "RandN"       "ID"          "TimeP"       "Site"        "Genotype"    "Treat"       "Treatment"  
 [8] "Orig"        "Origin"      "Set"         "Site.Orig"   "SA_cm2"      "Chl_ug.cm2"  "Sym10.6_cm2"
ThermData<-merge(ThermData, PAM.a, all.x=TRUE, all.y=FALSE)

Write Out Datasets

##Main Coral Data
write.csv(CoralData, "Outputs/CoralData.csv", row.names=FALSE)

##Thermal Tolerance Assay
write.csv(ThermData, "Outputs/ThermData.csv", row.names=FALSE)
LS0tDQp0aXRsZTogIkNhbGN1bGF0aW9uIG9mIFBoeXNpb2xvZ2ljYWwgTWV0cmljcyINCmF1dGhvcjogIlNlcmVuYSBIYWNrZXJvdHQiDQpkYXRlOiAiMS8xLzIwMjQiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICBkZl9wcmludDogcGFnZWQNCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQotLS0NCg0KIyBTZXR1cA0KDQpgYGB7ciBTZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkNCmBgYA0KDQoNCiMjIyBMb2FkIFBhY2thZ2VzDQpgYGB7cn0NCiMjSW5zdGFsbCBQYWNrYWdlcyBpZiBOZWVkZWQNCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCmlmICghcmVxdWlyZSgicGx5ciIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwbHlyIikNCg0KIyNMb2FkIFBhY2thZ2VzDQpsaWJyYXJ5KGdncGxvdDIpICNSZXF1aXJlZCBmb3IgZ2dwbG90cw0KbGlicmFyeShwbHlyKSAjUmVxdWlyZWQgZm9yIHJlbmFtZSBmdW5jdGlvbg0KYGBgDQoNCg0KIyMjIEdyYXBoaW5nIFBhcmFtZXRlcnMNCmBgYHtyfQ0KI05vdGU6IFJ1biAiR3JhcGhpbmcgUGFyYW1ldGVycyIgc2VjdGlvbiBmcm9tIDAxX0V4cGVyaW1lbnRhbFNldHVwLlJtZCBmaWxlDQpgYGANCg0KDQojIFNhbXBsZSBEYXRhIGFuZCBNZXRhZGF0YQ0KDQojIyMgTG9hZCBhbmQgT3JnYW5pemUgRGF0YQ0KYGBge3J9DQojIyMjTG9hZCBEYXRhDQoNClByb3Q8LXJlYWQuY3N2KCJEYXRhL1Byb3RlaW4uY3N2IiwgaGVhZGVyPVRSVUUpDQpCaW88LXJlYWQuY3N2KCJEYXRhL0Jpb21hc3MuY3N2IiwgaGVhZGVyPVRSVUUpDQpTeW08LXJlYWQuY3N2KCJEYXRhL1N5bWJpb250cy5jc3YiLCBoZWFkZXI9VFJVRSkNCkNobDwtcmVhZC5jc3YoIkRhdGEvQ2hsb3JvcGh5bGwuY3N2IiwgaGVhZGVyPVRSVUUpDQpQQU08LXJlYWQuY3N2KCJEYXRhL1BBTURhdGEuY3N2IiwgaGVhZGVyPVRSVUUpDQpQQU1fTWV0YTwtcmVhZC5jc3YoIkRhdGEvUEFNTWV0YS5jc3YiLCBoZWFkZXI9VFJVRSkNCkJDQS5TdGFuZDwtcmVhZC5jc3YoIkRhdGEvQkNBU3RhbmRhcmRzLmNzdiIsIGhlYWRlcj1UUlVFKQ0KV2F4LlN0YW5kPC1yZWFkLmNzdigiRGF0YS9XYXhTdGFuZGFyZHMuY3N2IiwgaGVhZGVyPVRSVUUpDQpTYW1wRGF0YTwtcmVhZC5jc3YoIkRhdGEvU2FtcGxlcy5jc3YiLCBoZWFkZXI9VFJVRSkNCg0KDQojIyMjU2FtcGxlIE1ldGEgRGF0YQ0Kc3RyKFNhbXBEYXRhKQ0KDQojI1NldCBmYWN0b3IgdmFyaWFibGVzDQpTYW1wRGF0YSRUaW1lUDwtZmFjdG9yKFNhbXBEYXRhJFRpbWVQLCBsZXZlbHM9YygiSU4iLCAiVFAxIiwgIlRQMiIsICJUUDMiLCAiVFA0IikpDQpTYW1wRGF0YSRTaXRlPC1mYWN0b3IoU2FtcERhdGEkU2l0ZSwgbGV2ZWxzPWMoIktMIiwgIlNTIikpDQpTYW1wRGF0YSRHZW5vdHlwZTwtZmFjdG9yKFNhbXBEYXRhJEdlbm90eXBlLCBsZXZlbHM9YygiQUM4IiwgIkFDMTAiLCAiQUMxMiIpKQ0KU2FtcERhdGEkT3JpZzwtZmFjdG9yKFNhbXBEYXRhJE9yaWcsIGxldmVscz1jKCJOIiwgIlQiKSkNClNhbXBEYXRhJE9yaWdpbjwtZmFjdG9yKFNhbXBEYXRhJE9yaWdpbiwgbGV2ZWxzPWMoIk5hdGl2ZSIsICJUcmFuc3BsYW50IikpDQoNCiMjQWRkIGEgU2FtcGxlIFNldCBWYXJpYWJsZQ0KU2FtcERhdGEkU2V0PC1wYXN0ZShTYW1wRGF0YSRUaW1lUCwgU2FtcERhdGEkU2l0ZSwgU2FtcERhdGEkR2Vub3R5cGUsIFNhbXBEYXRhJFRyZWF0LCBTYW1wRGF0YSRPcmlnLCBzZXA9Ii4iKQ0KDQojI0FkZCBTaXRlLk9yaWcgdmFyaWFibGUNClNhbXBEYXRhJFNpdGUuT3JpZzwtcGFzdGUoU2FtcERhdGEkU2l0ZSwgU2FtcERhdGEkT3JpZywgc2VwPSIuIikNClNhbXBEYXRhJFNpdGUuT3JpZzwtZmFjdG9yKFNhbXBEYXRhJFNpdGUuT3JpZywgbGV2ZWxzPWMoIktMLk4iLCAiS0wuVCIsICJTUy5OIiwgIlNTLlQiKSkNCg0KDQpgYGANCg0KDQojIyMgU2FtcGxlIFN1cmZhY2UgQXJlYQ0KYGBge3J9DQojIyMjQ3JlYXRlIFN0YW5kYXJkIEN1cnZlDQoNCiMjQ2FsY3VsYXRlIFN1cmZhY2UgQXJlYSBvZiBDeWxpbmRlcnMgZnJvbSBTdGFuZGFyZHMNCldheC5TdGFuZCRTQV9jbTI8LTIqcGkqKFdheC5TdGFuZCREbV9jbS8yKSpXYXguU3RhbmQkSHRfY20rMipwaSooV2F4LlN0YW5kJERtX2NtLzIpXjINCg0KIyNDYWxjdWxhdGUgRGlmZmVyZW5jZSBpbiBXYXggV2VpZ2h0DQpXYXguU3RhbmQkV2F4LkRfZzwtIFdheC5TdGFuZCRXYXguRl9nLVdheC5TdGFuZCRXYXguSV9nDQoNCiMjTGluZWFyIE1vZGVsIG9mIFNBIGFzIGEgRnVuY3Rpb24gb2YgV2F4IFdlaWdodA0Kd2F4LlNBLmxtICA8LSBsbShTQV9jbTJ+V2F4LkRfZywgZGF0YT1XYXguU3RhbmQpDQpzdW1tYXJ5KHdheC5TQS5sbSkNCmNvZWYod2F4LlNBLmxtKQ0KDQpTQS5tb2QgPC0gZnVuY3Rpb24od2F4LndlaWdodCkgew0KICBjb2VmcyA8LSBjb2VmKHdheC5TQS5sbSkNCiAgI3kgPSBteCArIGINCiAgU0EgPC0gKChjb2Vmc1syXSAqIHdheC53ZWlnaHQpICsgY29lZnNbMV0pDQogIHJldHVybihTQSl9DQoNCiMjIyNBcHBseSBTdGFuZGFyZCBDdXJ2ZQ0KDQojI0NhbGN1bGF0ZSBEaWZmZXJlbmNlIGluIFdheCBXZWlnaHQgKGcpIGluIFNhbXBsZSBEYXRhDQpTYW1wRGF0YSRXYXguRF9nPC0gU2FtcERhdGEkV2F4LkZfZy1TYW1wRGF0YSRXYXguSV9nDQoNCiMjQ2FsY3VsYXRlIFN1cmZhY2UgQXJlYSAoY21eMikgYnkgQXBwbHlpbmcgTGluZWFyIE1vZGVsIEZ1bmN0aW9uDQpTYW1wRGF0YSRTQV9jbTI8LVNBLm1vZChTYW1wRGF0YSRXYXguRF9nKQ0KDQpgYGANCg0KDQojIyMgU3Vic2V0IFNhbXBsZSBNZXRhRGF0YSBieSBFeHBlcmltZW50DQpgYGB7cn0NCiMjTWFpbiBDb3JhbHMgaW4gdGhlIE51cnNlcnkNCkNvcmFsc19NYWluPC1zdWJzZXQoU2FtcERhdGEsIFRyZWF0PT0iTSIpDQoNCiMjVGhlcm1hbCBUb2xlcmFuY2UgQXNzYXkNCkNvcmFsc19UaGVybTwtc3Vic2V0KFNhbXBEYXRhLCBUcmVhdD09IkMiIHwgVHJlYXQ9PSJIIikNCmBgYA0KDQoNCiMgUHJvdGVpbg0KDQojIyMgQ2FsY3VsYXRlIFByb3RlaW4gQ29uY2VudHJhdGlvbg0KYGBge3J9DQojIyMjQ3JlYXRlIFN0YW5kYXJkIEN1cnZlDQoNCiMjU3Vic2V0IFN0YW5kYXJkcyBEYXRhDQpQcm90LlN0PC0gc3Vic2V0KFByb3QsIElucHV0PT0iU3RhbmRhcmQiKQ0KDQojI01lcmdlIFN0YW5kYXJkIE1ldGEgRGF0YSB3aXRoIEFic29yYmFuY2UgZGF0YQ0KI01lcmdlcyBieSBSYW5kb20gTnVtYmVyIChSYW5kTikgY29sdW1uDQpCQ0FTdGFuZHM8LW1lcmdlKEJDQS5TdGFuZCwgUHJvdC5TdCwgYWxsLng9VFJVRSkNCg0KIyNQbG90IFByb3RlaW4gQ29uY2VudHJhdGlvbiBhcyBhIGZ1bmN0aW9uIG9mIEFic29yYmFuY2UgDQpwbG90KEJDQVN0YW5kcyRBNTYyLCBCQ0FTdGFuZHMkUHJvdGVpbl91Zy5tbCwgcGNoPTE5KQ0KDQojI0ZpdCBNb2RlbHMgb2YgUHJvdGVpbiBDb25jZW50cmF0aW9uIGFzIGEgZnVuY3Rpb24gb2YgQWJzb3JiYW5jZSANCg0KI0ZpcnN0IGRlZ3JlZSBwb2x5bm9taWFsIGVxdWF0aW9uOg0KQkNBLmxtICA8LSBsbShQcm90ZWluX3VnLm1sfkE1NjIsIGRhdGE9QkNBU3RhbmRzKQ0KI1NlY29uZCBkZWdyZWUgcG9seW5vbWlhbCBlcXVhdGlvbjoNCkJDQS5wbG95MiA8LSBsbShQcm90ZWluX3VnLm1sfnBvbHkoQTU2MiwyLHJhdz1UUlVFKSwgZGF0YT1CQ0FTdGFuZHMpDQojVGhpcmQgZGVncmVlIHBvbHlub21pYWwgZXF1YXRpb246DQpCQ0EucGxveTMgPC0gbG0oUHJvdGVpbl91Zy5tbH5wb2x5KEE1NjIsMyxyYXc9VFJVRSksIGRhdGE9QkNBU3RhbmRzKQ0KDQojI0FkZCBNb2RlbHMgdG8gUGxvdA0KeHggPC0gc2VxKDAsMywgbGVuZ3RoPTUwKQ0KDQpsaW5lcyh4eCwgcHJlZGljdChCQ0EubG0sIG5ld2RhdGE9ZGF0YS5mcmFtZShBNTYyPXh4KSksIGNvbD0icmVkIikNCmxpbmVzKHh4LCBwcmVkaWN0KEJDQS5wbG95MiwgbmV3ZGF0YT1kYXRhLmZyYW1lKEE1NjI9eHgpKSwgY29sPSJncmVlbiIpDQpsaW5lcyh4eCwgcHJlZGljdChCQ0EucGxveTMsIG5ld2RhdGE9ZGF0YS5mcmFtZShBNTYyPXh4KSksIGNvbD0iYmx1ZSIpDQoNCiMjQ29tcGFyZSBNb2RlbHMgZm9yIEJlc3QgRml0DQphbm92YShCQ0EubG0sIEJDQS5wbG95MikNCiNQb2x5MiBpcyBhIHNpZ25pZmljYW50bHkgYmV0dGVyIGZpdCB0aGFuIGxpbmVhcg0KDQphbm92YShCQ0EucGxveTIsIEJDQS5wbG95MykNCiNQb2x5MyBpcyBzaWduaWZpY2FudGx5IGJldHRlciBmaXQgdGhhbiBQbG95Mg0KDQojI0NyZWF0ZSBhIGZ1bmN0aW9uIHdpdGggdGhlIFBvbHkzIG1vZGVsIEVxdWF0aW9uDQpzdW1tYXJ5KEJDQS5wbG95MykNCmNvZWYoQkNBLnBsb3kzKQ0KDQpUUC5tb2QgPC0gZnVuY3Rpb24oYWJzb3JiYW5jZSkgew0KICBjb2VmcyA8LSBjb2VmKEJDQS5wbG95MykNCiAgI3kgPSBkICsgY3ggKyBieF4yICsgYXheMw0KICBwcm90ZWluIDwtIGNvZWZzWzFdICsgKGNvZWZzWzJdICogYWJzb3JiYW5jZSkgKyAoY29lZnNbM10gKiBhYnNvcmJhbmNlXjIpICsgKGNvZWZzWzRdICogYWJzb3JiYW5jZV4zKQ0KICByZXR1cm4ocHJvdGVpbil9DQoNCg0KIyMjI0FwcGx5IFN0YW5kYXJkIEN1cnZlDQoNCiMjU3Vic2V0IFNhbXBsZSBEYXRhIChVbmtub3duIFNhbXBsZSkNClByb3QuVW48LSBzdWJzZXQoUHJvdCwgSW5wdXQ9PSJVbiIpDQoNCiMjQ2FsY3VsYXRlIFByb3RlaW4gQ29uY2VudHJhdGlvbiAodWcvbWwpDQpQcm90LlVuJFRQX3VnLm1sPC1UUC5tb2QoUHJvdC5VbiRBNTYyKQ0KDQojI01lcmdlIHdpdGggU2FtcGxlIE1ldGEgRGF0YSB0byBDYWxjdWxhdGUgUHJvdGVpbiBwZXIgU3VyZmFjZSBBcmVhDQojTWVyZ2VzIGJ5IFJhbmRvbSBOdW1iZXIgKFJhbmROKSBjb2x1bW4NCiNBZGRzIG5lY2Vzc2FyeSBTbHVycnkgVm9sdW1lIChWb2xfbWwpIGFuZCBTdXJmYWNlIEFyZWEgKFNBX2NtMikgY29sdW1ucw0KI1JldGFpbnMgU2FtcGxlIE1ldGEgRGF0YSBvbmx5IGZvciBzYW1wbGVzIHdpdGggUHJvdGVpbiBkYXRhIChNYWluIHNhbXBsZXMgb25seSkNClByb3QuVW48LW1lcmdlKFByb3QuVW4sIFNhbXBEYXRhLCBhbGwueD1UUlVFLCBhbGwueT1GQUxTRSkNCg0KIyNDYWxjdWxhdGUgVG90YWwgUHJvdGVpbiAodWcpIA0KUHJvdC5VbiRUUF91ZzwtUHJvdC5VbiRUUF91Zy5tbCpQcm90LlVuJFZvbF9tbA0KDQojI0NhbGN1bGF0ZSBQcm90ZWluIHBlciBTdXJmYWNlIEFyZWEgKHVnL2NtXjIpDQpQcm90LlVuJFRQX3VnLmNtMjwtUHJvdC5VbiRUUF91Zy9Qcm90LlVuJFNBX2NtMg0KDQojI1NlcGFyYXRlIENvcmFsIGFuZCBTeW1iaW9udCBGcmFjdGlvbnMNClByb3QuQzwtIHN1YnNldChQcm90LlVuLCBGcmFjdGlvbj09IkMiKQ0KUHJvdC5DPC1yZW5hbWUoUHJvdC5DLCBjKCJUUF91Zy5jbTIiID0gIlRQX3VnLmNtMl9DIikpDQoNClByb3QuUzwtIHN1YnNldChQcm90LlVuLCBGcmFjdGlvbj09IlMiKQ0KUHJvdC5TPC1yZW5hbWUoUHJvdC5TLCBjKCJUUF91Zy5jbTIiID0gIlRQX3VnLmNtMl9TIikpDQpgYGANCg0KDQojIyMgQ2hlY2sgZm9yIE91dGxpZXJzDQpDaGVjayBmb3IgT3V0bGllcnMgYnkgVGltZXBvaW50LCBncm91cGVkIGJ5IHNhbXBsZSBzZXQuIFJlbW92aW5nIGFueSBjbGVhciBvdXRsaWVyIHNhbXBsZXMgYW5kIG91dGxpZXJzIG9mIHRlY2huaWNhbCByZXBsaWNhdGVzIGJlZm9yZSBhdmVyYWdpbmcgYWNyb3NzIHRlY2huaWNhbCByZXBsaWF0ZXMuIA0KDQojIyMjIENvcmFsIEhvc3QNCmBgYHtyfQ0KIyNJbml0aWFsIFZpc3VhbCBDaGVjaw0KZ2dwbG90KFByb3QuQywgYWVzKHg9U2V0LCB5PVRQX3VnLmNtMl9DKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiMjQ2hlY2sgZm9yIE91dGxpZXJzIGJ5IFRpbWVwb2ludA0KDQojVFAxDQpnZ3Bsb3Qoc3Vic2V0KFByb3QuQywgVGltZVA9PSJUUDEiKSwgYWVzKHg9U2V0LCB5PVRQX3VnLmNtMl9DKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSg1MCwxMDAwKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiNUUDINCmdncGxvdChzdWJzZXQoUHJvdC5DLCBUaW1lUD09IlRQMiIpLCBhZXMoeD1TZXQsIHk9VFBfdWcuY20yX0MpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDUwLDEwMDApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KUHJvdC5DJFJhbmROW3doaWNoKFByb3QuQyRUaW1lUD09IlRQMiIgJiBQcm90LkMkVFBfdWcuY20yX0M8MTIwKV0gIyAiMTI1IiAiMTI2IiAiMTI3Ig0KDQojTW9udGggVFAzDQpnZ3Bsb3Qoc3Vic2V0KFByb3QuQywgVGltZVA9PSJUUDMiKSwgYWVzKHg9U2V0LCB5PVRQX3VnLmNtMl9DKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgxMDAsMTAwMCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpQcm90LkMkUmFuZE5bd2hpY2goUHJvdC5DJFRpbWVQPT0iVFAzIiAmIFByb3QuQyRUUF91Zy5jbTJfQz43MDApXSAjIjE4NiIgIjE4NyIgIjE4OCINCg0KI01vbnRoIFRQNA0KZ2dwbG90KHN1YnNldChQcm90LkMsIFRpbWVQPT0iVFA0IiksIGFlcyh4PVNldCwgeT1UUF91Zy5jbTJfQykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oNTAsMTEwMCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpQcm90LkMkUmFuZE5bd2hpY2goUHJvdC5DJFRpbWVQPT0iVFA0IiAmIFByb3QuQyRUUF91Zy5jbTJfQz42MDApXSAjIjIxMSIgIjIyMiIgIjIyMiIgIjIyMiINCg0KIyNSZW1vdmUgT3V0bGllciBSZWFkaW5ncw0KUHJvdC5DLm88LVByb3QuQ1stYyh3aGljaCgoUHJvdC5DJFRpbWVQPT0iVFAyIiAmIFByb3QuQyRUUF91Zy5jbTJfQzwxMjApIHwNCihQcm90LkMkVGltZVA9PSJUUDMiICYgUHJvdC5DJFRQX3VnLmNtMl9DPjcwMCkgfA0KKFByb3QuQyRUaW1lUD09IlRQNCIgJiBQcm90LkMkVFBfdWcuY20yX0M+NjAwKSkpLF0NCg0KIyNWaXN1YWwgQ2hlY2sNCmdncGxvdChQcm90LkMubywgYWVzKHg9U2V0LCB5PVRQX3VnLmNtMl9DKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgxMDAsNjAwKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCmBgYA0KDQoNCiMjIyMgU3ltYmlvbnQNCmBgYHtyfQ0KIyNJbml0aWFsIFZpc3VhbCBDaGVjaw0KZ2dwbG90KFByb3QuUywgYWVzKHg9U2V0LCB5PVRQX3VnLmNtMl9TKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiMjQ2hlY2sgZm9yIE91dGxpZXJzIGJ5IFRpbWVwb2ludA0KI1RQMQ0KZ2dwbG90KHN1YnNldChQcm90LlMsIFRpbWVQPT0iVFAxIiksIGFlcyh4PVNldCwgeT1UUF91Zy5jbTJfUykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oNTAsIDEyMDApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KUHJvdC5TJFJhbmROW3doaWNoKFByb3QuUyRUaW1lUD09IlRQMSIgJiBQcm90LlMkVFBfdWcuY20yX1M+NzUwKV0gIyI0OSIgIjUyIiAiODQiDQoNCiNUUDINCmdncGxvdChzdWJzZXQoUHJvdC5TLCBUaW1lUD09IlRQMiIpLCBhZXMoeD1TZXQsIHk9VFBfdWcuY20yX1MpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDUwLDEwMDApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KUHJvdC5TJFJhbmROW3doaWNoKFByb3QuUyRUaW1lUD09IlRQMiIgJiBQcm90LlMkVFBfdWcuY20yX1M+NTAwICYgUHJvdC5TJFNpdGU9PSJTUyIgJiBQcm90LlMkR2Vub3R5cGU9PSJBQzgiKV0gIyIxMjkiDQoNCiNUUDMNCmdncGxvdChzdWJzZXQoUHJvdC5TLCBUaW1lUD09IlRQMyIpLCBhZXMoeD1TZXQsIHk9VFBfdWcuY20yX1MpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDUwLDEwMDApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQNA0KZ2dwbG90KHN1YnNldChQcm90LlMsIFRpbWVQPT0iVFA0IiksIGFlcyh4PVNldCwgeT1UUF91Zy5jbTJfUykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oNTAsMTAwMCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpQcm90LlMkUmFuZE5bd2hpY2goUHJvdC5TJFRpbWVQPT0iVFA0IiAmIFByb3QuUyRUUF91Zy5jbTJfUz43NTApXSAjIjIyMiIgIjIyMiIgIjIyMiINCg0KIyNSZW1vdmUgT3V0bGllciBSZWFkaW5ncw0KUHJvdC5TLm88LVByb3QuU1stYyh3aGljaCgoUHJvdC5TJFRpbWVQPT0iVFAxIiAmIFByb3QuUyRUUF91Zy5jbTJfUz43NTApIHwNCihQcm90LlMkVGltZVA9PSJUUDIiICYgUHJvdC5TJFRQX3VnLmNtMl9TPjUwMCAmIFByb3QuUyRTaXRlPT0iU1MiICYgUHJvdC5TJEdlbm90eXBlPT0iQUM4IikgfA0KKFByb3QuUyRUaW1lUD09IlRQNCIgJiBQcm90LlMkVFBfdWcuY20yX1M+NzUwKSkpLF0NCg0KIyNWaXN1YWwgQ2hlY2sNCmdncGxvdChQcm90LlMubywgYWVzKHg9U2V0LCB5PVRQX3VnLmNtMl9TKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgxMDAsNzUwKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCmBgYA0KDQoNCiMjIyBBZGQgUHJvdGVpbiB0byBNYWluIENvcmFsIERhdGENCkFkZCBob3N0IGFuZCBzeW1iaW9udCBmcmFjdGlvbnMgZm9yIGEgdG90YWwgaG9sb2Jpb250IHZhbHVlIHRvIGJlIHVzZWQgZm9yIGRvd25zdHJlYW0gYW5hbHlzaXMuDQoNCmBgYHtyfQ0KIyMjI0F2ZXJhZ2UgQWNyb3NzIFJlcGxpY2F0ZSBSZWFkaW5ncyAoIlJlcCIgY29sdW1uOiBBLCBCLCBDKQ0KbmFtZXMoUHJvdC5DLm8pDQpQcm90LkMuYTwtYWdncmVnYXRlKFByb3QuQy5vJFRQX3VnLmNtMl9DLCBsaXN0KFByb3QuQy5vJFJhbmROLCBQcm90LkMubyRJRCksIG1lYW4pDQpuYW1lcyhQcm90LkMuYSk8LWMoIlJhbmROIiwgIklEIiwgIlRQX3VnLmNtMl9DIikNCg0KbmFtZXMoUHJvdC5TLm8pDQpQcm90LlMuYTwtYWdncmVnYXRlKFByb3QuUy5vJFRQX3VnLmNtMl9TLCBsaXN0KFByb3QuUy5vJFJhbmROLCBQcm90LlMubyRJRCksIG1lYW4pDQpuYW1lcyhQcm90LlMuYSk8LWMoIlJhbmROIiwgIklEIiwgIlRQX3VnLmNtMl9TIikNCg0KIyMjIyBBZGQgSG9zdCBhbmQgU3ltYmlvbnQgZm9yIEhvbG9iaW9udCANClByb3QuSG9sPC1tZXJnZShQcm90LkMuYSwgUHJvdC5TLmEsIGFsbC54PVRSVUUpDQpQcm90LkhvbCRUUF91Zy5jbTI8LShQcm90LkhvbCRUUF91Zy5jbTJfQyArIFByb3QuSG9sJFRQX3VnLmNtMl9TKQ0KDQojIyMjTWVyZ2UgQXZlcmFnZWQgSG9sb2Jpb250IFByb3RlaW4gRGF0YSB3aXRoIENvcmFsIE1haW4gRGF0YQ0KI01lcmdlcyBieSBSYW5kb20gTnVtYmVyIChSYW5kTikgYW5kIElEIGNvbHVtbnMNCiNSZXRhaW5zIGFsbCBNYWluIHNhbXBsZXMNCiNSZXRhaW5zIFJhbmROLCBJRCwgVGltZVAsIFNpdGUsIEdlbm90eXBlLCBPcmlnLCBPcmlnaW4sIFNldCwgYW5kIFNBX2NtMiBmcm9tIENvcmFsc19NYWluDQpuYW1lcyhDb3JhbHNfTWFpbikNCkNvcmFsRGF0YTwtbWVyZ2UoQ29yYWxzX01haW5bLGMoMTo1LCA4OjksIDEzOjE0LCAxNildLCBQcm90LkhvbFssYygxOjIsIDUpXSwgYWxsLng9VFJVRSkNCg0KYGBgDQoNCg0KIyBCaW9tYXNzDQoNCiMjIyBDYWxjdWxhdGUgQXNoIEZyZWUgRHJ5IFdlaWdodA0KYGBge3J9DQojI0NhbGN1bGF0ZSBDaGFuZ2UgaW4gV2VpZ2h0IGFmdGVyIEJ1cm5pbmcgKGcpDQpCaW8kRGVsdGFCdXJuX2c8LUJpbyREcmllZF9nLUJpbyRCdXJuZWRfZw0KDQojI0NhbGN1bGF0ZSBBc2ggRnJlZSBEcnkgV2VpZ2h0IChBRkRXKSAoZykgcGVyIFZvbHVtZSBJbnB1dCBvZiBUaXNzdWUgKG1sKSANCkJpbyRBRkRXX2cubWw8LUJpbyREZWx0YUJ1cm5fZy9CaW8kSW5Wb2xfbWwNCg0KIyNNZXJnZSB3aXRoIFNhbXBsZSBNZXRhIERhdGEgdG8gQ2FsY3VsYXRlIEJpb21hc3MgcGVyIFN1cmZhY2UgQXJlYQ0KI01lcmdlcyBieSBSYW5kb20gTnVtYmVyIChSYW5kTikgY29sdW1uDQojQWRkcyBuZWNlc3NhcnkgU2x1cnJ5IFZvbHVtZSAoVm9sX21sKSBhbmQgU3VyZmFjZSBBcmVhIChTQV9jbTIpIGNvbHVtbnMNCiNSZXRhaW5zIFNhbXBsZSBNZXRhIERhdGEgb25seSBmb3Igc2FtcGxlcyB3aXRoIEJpb21hc3MgZGF0YSAoTWFpbiBzYW1wbGVzIG9ubHkpDQpCaW88LW1lcmdlKEJpbywgU2FtcERhdGEsIGFsbC54PVRSVUUsIGFsbC55PUZBTFNFKQ0KDQojI0NhbGN1bGF0ZSBUb3RhbCBBRkRXIChnKSANCkJpbyRBRkRXX2c8LUJpbyRBRkRXX2cubWwqQmlvJFZvbF9tbA0KDQojI0NhbGN1bGF0ZSBBRkRXIHBlciBTdXJmYWNlIEFyZWEgKG1nL2NtXjIpDQpCaW8kQUZEV19nLmNtMjwtQmlvJEFGRFdfZy9CaW8kU0FfY20yDQpCaW8kQUZEV19tZy5jbTIgPC0gQmlvJEFGRFdfZy5jbTIgKiAxMDAwDQoNCiMjU2VwYXJhdGUgQ29yYWwgYW5kIFN5bWJpb250IEZyYWN0aW9ucw0KQmlvLkM8LXN1YnNldChCaW8sIEZyYWN0aW9uPT0iQyIpDQpCaW8uQzwtcmVuYW1lKEJpby5DLCBjKCJBRkRXX21nLmNtMiIgPSAiQUZEV19tZy5jbTJfQyIpKQ0KDQpCaW8uUzwtc3Vic2V0KEJpbywgRnJhY3Rpb249PSJaIikNCkJpby5TPC1yZW5hbWUoQmlvLlMsIGMoIkFGRFdfbWcuY20yIiA9ICJBRkRXX21nLmNtMl9TIikpDQoNCmBgYA0KDQoNCiMjIyBDaGVjayBmb3IgT3V0bGllcnMNCkNoZWNrIGZvciBPdXRsaWVycyBieSBUaW1lcG9pbnQsIGdyb3VwZWQgYnkgc2FtcGxlIHNldC4gUmVtb3ZpbmcgYW55IGNsZWFyIG91dGxpZXIgc2FtcGxlcy4gDQoNCiMjIyMgQ29yYWwgSG9zdA0KYGBge3J9DQojI0luaXRpYWwgVmlzdWFsIENoZWNrDQpnZ3Bsb3QoQmlvLkMsIGFlcyh4PVNldCwgeT1BRkRXX21nLmNtMl9DKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiMjQ2hlY2sgZm9yIE91dGxpZXJzIGJ5IFRpbWVwb2ludA0KDQojVFAxDQpnZ3Bsb3Qoc3Vic2V0KEJpby5DLCBUaW1lUD09IlRQMSIpLCBhZXMoeD1TZXQsIHk9QUZEV19tZy5jbTJfQykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCwyLjUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQMg0KZ2dwbG90KHN1YnNldChCaW8uQywgVGltZVA9PSJUUDIiKSwgYWVzKHg9U2V0LCB5PUFGRFdfbWcuY20yX0MpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMi41KSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiNUUDMNCmdncGxvdChzdWJzZXQoQmlvLkMsIFRpbWVQPT0iVFAzIiksIGFlcyh4PVNldCwgeT1BRkRXX21nLmNtMl9DKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIuNSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojVFA0DQpnZ3Bsb3Qoc3Vic2V0KEJpby5DLCBUaW1lUD09IlRQNCIpLCBhZXMoeD1TZXQsIHk9QUZEV19tZy5jbTJfQykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCwzLjUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KQmlvLkMkUmFuZE5bd2hpY2goQmlvLkMkVGltZVA9PSJUUDQiICYgQmlvLkMkQUZEV19tZy5jbTJfQz4zKV0gIzIyMiAjQWxzbyBvdXRsaWVyIGZvciBQcm90ZWluDQoNCiMjUmVtb3ZlIE91dGxpZXJzIA0KQmlvLkMubzwtQmlvLkNbLWMod2hpY2goQmlvLkMkVGltZVA9PSJUUDQiICYgQmlvLkMkQUZEV19tZy5jbTJfQz4zKSksXQ0KDQojI1Zpc3VhbCBDaGVjaw0KZ2dwbG90KEJpby5DLm8sIGFlcyh4PVNldCwgeT1BRkRXX21nLmNtMl9DKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIuNSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpgYGANCg0KDQoNCiMjIyMgU3ltYmlvbnQNCmBgYHtyfQ0KIyNJbml0aWFsIFZpc3VhbCBDaGVjaw0KZ2dwbG90KEJpby5TLCBhZXMoeD1TZXQsIHk9QUZEV19tZy5jbTJfUykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojI0NoZWNrIGZvciBPdXRsaWVycyBieSBUaW1lcG9pbnQNCg0KI1RQMQ0KZ2dwbG90KHN1YnNldChCaW8uUywgVGltZVA9PSJUUDEiKSwgYWVzKHg9U2V0LCB5PUFGRFdfbWcuY20yX1MpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMS41KSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiNUUDINCmdncGxvdChzdWJzZXQoQmlvLlMsIFRpbWVQPT0iVFAyIiksIGFlcyh4PVNldCwgeT1BRkRXX21nLmNtMl9TKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDEuNSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojVFAzDQpnZ3Bsb3Qoc3Vic2V0KEJpby5TLCBUaW1lUD09IlRQMyIpLCBhZXMoeD1TZXQsIHk9QUZEV19tZy5jbTJfUykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCwxLjUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQNA0KZ2dwbG90KHN1YnNldChCaW8uUywgVGltZVA9PSJUUDQiKSwgYWVzKHg9U2V0LCB5PUFGRFdfbWcuY20yX1MpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMikrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpCaW8uUyRSYW5kTlt3aGljaChCaW8uUyRUaW1lUD09IlRQNCIgJiBCaW8uUyRBRkRXX21nLmNtMl9TPjEuNSldICMyMjIgI0Fsc28gb3V0bGllciBmb3IgUHJvdGVpbiBhbmQgQmlvbWFzcyBvZiBIb3N0DQoNCg0KIyNSZW1vdmUgT3V0bGllcnMgDQpCaW8uUy5vPC1CaW8uU1stYyh3aGljaChCaW8uUyRUaW1lUD09IlRQNCIgJiBCaW8uUyRBRkRXX21nLmNtMl9TPjEuNSkpLF0NCg0KIyNWaXN1YWwgQ2hlY2sNCmdncGxvdChCaW8uUy5vLCBhZXMoeD1TZXQsIHk9QUZEV19tZy5jbTJfUykpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCwxLjUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KYGBgDQoNCg0KIyMjIEFkZCBCaW9tYXNzIHRvIE1haW4gQ29yYWwgRGF0YQ0KQWRkIGhvc3QgYW5kIHN5bWJpb250IGZyYWN0aW9ucyBmb3IgYSB0b3RhbCBob2xvYmlvbnQgdmFsdWUgdG8gYmUgdXNlZCBmb3IgZG93bnN0cmVhbSBhbmFseXNpcy4NCg0KYGBge3J9DQojIyMjIEFkZCBIb3N0IGFuZCBTeW1iaW9udCBmb3IgSG9sb2Jpb250IA0KQmlvLkhvbDwtbWVyZ2UoQmlvLkMubywgQmlvLlMubywgYWxsLng9VFJVRSkNCkJpby5Ib2wkQUZEV19tZy5jbTI8LShCaW8uSG9sJEFGRFdfbWcuY20yX0MgKyBCaW8uSG9sJEFGRFdfbWcuY20yX1MpDQoNCiMjIyNNZXJnZSBBdmVyYWdlZCBIb2xvYmlvbnQgQmlvbWFzcyBEYXRhIHdpdGggQ29yYWwgTWFpbiBEYXRhDQojTWVyZ2VzIGJ5IElEIGNvbHVtbiBhbmQgYWRkcyBBRkRXIChtZy9jbV4yKSAoQUZEV19tZy5jbTIpIGNvbHVtbiBmcm9tIEJpb21hc3MgZGF0YWZyYW1lDQojUmV0YWlucyBhbGwgTWFpbiBzYW1wbGVzDQpDb3JhbERhdGE8LW1lcmdlKENvcmFsRGF0YSwgQmlvLkhvbFssYygxOjIsIDUpXSwgYWxsLng9VFJVRSkNCg0KYGBgDQoNCg0KIyBDaGxvcm9waHlsbA0KDQojIyMgQ2FsY3VsYXRlIENobG9yb3BoeWxsIENvbmNlbnRyYXRpb24NCkVxdWF0aW9ucyBmb3IgRGlub3MgZnJvbSBKZWZmcmV5IGFuZCBIdW1waHJleSAxOTc1IGluIDEwMCUgYWNldG9uZQ0KQ2hsYSA9IDExLjQzICogQTY2MyAtIDAuNjQgKiBBNjMwDQpDaGxjMiA9IDI3LjA5ICogQTYzMCAtIDMuNjMgKiBBNjYzDQpgYGB7cn0NCiMjU3VidHJhY3QgQmFja2dyb3VuZCBBNzUwIGZyb20gQTYzMCBhbmQgQTY2Mw0KQ2hsJEE2MzAuYzwtQ2hsJEE2MzAtQ2hsJEE3NTANCkNobCRBNjYzLmM8LUNobCRBNjYzLUNobCRBNzUwDQoNCiMjRGl2aWRlIGJ5IFBhdGhsZW5ndGggKDAuNWNtIHBhdGhsZW5ndGggZm9yIDE3NXVsIHNhbXBsZSBpbiBVVlN0YXIgUGxhdGUpIA0KQ2hsJEE2MzAuYzwtYyhDaGwkQTYzMC5jLzAuNSkNCkNobCRBNjYzLmM8LWMoQ2hsJEE2NjMuYy8wLjUpDQoNCiMjQ2FsY3VsYXRlIENobC1hIGFuZCBDaGwtYzIgaW4gdWcvbWwNCkNobCRDaGwuYV91Zy5tbDwtMTEuNDMqQ2hsJEE2NjMuYy0gMC42NCpDaGwkQTYzMC5jDQpDaGwkQ2hsLmMyX3VnLm1sIDwtIDI3LjA5KkNobCRBNjMwLmMgLSAzLjYzKkNobCRBNjYzLmMNCg0KIyNNZXJnZSB3aXRoIFNhbXBsZSBEYXRhIHRvIENhbGN1bGF0ZSBDaGxvcm9waHlsbCBwZXIgU3VyZmFjZSBBcmVhDQojTWVyZ2VzIGJ5IFJhbmRvbSBOdW1iZXIgKFJhbmROKSBjb2x1bW4NCiNBZGRzIG5lY2Vzc2FyeSBTbHVycnkgVm9sdW1lIChWb2xfbWwpIGFuZCBTdXJmYWNlIEFyZWEgKFNBX2NtMikgY29sdW1ucw0KQ2hsPC1tZXJnZShDaGwsIFNhbXBEYXRhLCAgYWxsPVRSVUUpDQoNCiMjQ2FsY3VsYXRlIFRvdGFsIENobG9yb3BoeWxsLWEgYW5kIGMyICh1ZykgDQpDaGwkQ2hsLmFfdWc8LUNobCRDaGwuYV91Zy5tbCpDaGwkVm9sX21sDQpDaGwkQ2hsLmMyX3VnPC1DaGwkQ2hsLmMyX3VnLm1sKkNobCRWb2xfbWwNCg0KIyNDYWxjdWxhdGUgQ2hsb3JvcGh5bGwtYSBhbmQgYzIgcGVyIFN1cmZhY2UgQXJlYSAodWcvY21eMikNCkNobCRDaGwuYV91Zy5jbTI8LUNobCRDaGwuYV91Zy9DaGwkU0FfY20yDQpDaGwkQ2hsLmMyX3VnLmNtMjwtQ2hsJENobC5jMl91Zy9DaGwkU0FfY20yDQoNCiMjSW5pdGlhbCBWaXN1YWwgQ2hlY2sNCmdncGxvdChDaGwsIGFlcyh4PVNldCwgeT1DaGwuYV91Zy5jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KZ2dwbG90KENobCwgYWVzKHg9U2V0LCB5PUNobC5jMl91Zy5jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KIyNTZXQgTmVnYXRpdmUgVmFsdWVzIHRvIFplcm8NCkNobCRDaGwuYV91Zy5jbTJbKHdoaWNoKENobCRDaGwuYV91Zy5jbTI8MCkpXTwtMA0KQ2hsJENobC5jMl91Zy5jbTJbKHdoaWNoKENobCRDaGwuYzJfdWcuY20yPDApKV08LTANCg0KIyNBZGQgQ2hsb3JvcGh5bGwtYSBhbmQgYzIgZm9yIFRvdGFsIENobG9yb3BoeWxsIHBlciBTdXJmYWNlIEFyZWEgKHVnL2NtXjIpDQpDaGwkQ2hsX3VnLmNtMjwtQ2hsJENobC5hX3VnLmNtMitDaGwkQ2hsLmMyX3VnLmNtMg0KDQojI1Zpc3VhbCBDaGVjaw0KZ2dwbG90KENobCwgYWVzKHg9U2V0LCB5PUNobF91Zy5jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KYGBgDQoNCg0KIyMjIENoZWNrIGZvciBPdXRsaWVycw0KQ2hlY2sgZm9yIE91dGxpZXJzIGJ5IFRyZWF0bWVudCBhbmQgVGltZXBvaW50LCBncm91cGVkIGJ5IHNhbXBsZSBzZXQuIFJlbW92aW5nIGNsZWFyIG91dGxpZXIgc2FtcGxlcyBhbmQgb3V0bGllcnMgb2YgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgYmVmb3JlIGF2ZXJhZ2luZyBhY3Jvc3MgdGVjaG5pY2FsIHJlcGxpYXRlcy4gDQoNCiMjIyMgTWFpbg0KYGBge3J9DQojI1N1YnNldCBNYWluIENvcmFscw0KQ2hsLk08LXN1YnNldChDaGwsIFRyZWF0PT0iTSIpDQoNCiNUUDENCmdncGxvdChzdWJzZXQoQ2hsLk0sIFRpbWVQPT0iVFAxIiksIGFlcyh4PVNldCwgeT1DaGxfdWcuY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIuNSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQoNCiNUUDINCmdncGxvdChzdWJzZXQoQ2hsLk0sIFRpbWVQPT0iVFAyIiksIGFlcyh4PVNldCwgeT1DaGxfdWcuY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDQuNSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojVFAzDQpnZ3Bsb3Qoc3Vic2V0KENobC5NLCBUaW1lUD09IlRQMyIpLCBhZXMoeD1TZXQsIHk9Q2hsX3VnLmNtMikpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCw0LjUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQNA0KZ2dwbG90KHN1YnNldChDaGwuTSwgVGltZVA9PSJUUDQiKSwgYWVzKHg9U2V0LCB5PUNobF91Zy5jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsNy41KSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCkNobC5NJFJhbmROW3doaWNoKENobC5NJFRpbWVQPT0iVFA0IiAmIENobC5NJENobF91Zy5jbTI+NildICMiMjIyIiAiMjIyIiAiMjIyIiAjQWxzbyBvdXRsaWVyIGZvciBQcm90ZWluIGFuZCBCaW9tYXNzDQoNCiMjUmVtb3ZlIE91dGxpZXJzIA0KQ2hsLk0ubzwtQ2hsLk1bLWMod2hpY2goQ2hsLk0kVGltZVA9PSJUUDQiICYgQ2hsLk0kQ2hsX3VnLmNtMj42KSksXQ0KDQpgYGANCg0KDQojIyMjIENvbnRyb2wNCmBgYHtyfQ0KIyNTdWJzZXQgQ29udHJvbCBUcmVhdG1lbnQgaW4gVGhlcm1hbCBUb2xlcmFuY2UgQXNzYXkgDQpDaGwuQzwtc3Vic2V0KENobCwgVHJlYXQ9PSJDIikNCg0KI0lODQpnZ3Bsb3Qoc3Vic2V0KENobC5DLCBUaW1lUD09IklOIiksIGFlcyh4PVNldCwgeT1DaGxfdWcuY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIuNSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpDaGwuQyRSYW5kTlt3aGljaChDaGwuQyRUaW1lUD09IklOIiAmIENobC5DJENobF91Zy5jbTI8MC4yNSldICMiVzJfNDUiDQoNCiNUUDENCmdncGxvdChzdWJzZXQoQ2hsLkMsIFRpbWVQPT0iVFAxIiksIGFlcyh4PVNldCwgeT1DaGxfdWcuY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIuNSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojVFAyDQpnZ3Bsb3Qoc3Vic2V0KENobC5DLCBUaW1lUD09IlRQMiIpLCBhZXMoeD1TZXQsIHk9Q2hsX3VnLmNtMikpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCwyLjUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQMw0KZ2dwbG90KHN1YnNldChDaGwuQywgVGltZVA9PSJUUDMiKSwgYWVzKHg9U2V0LCB5PUNobF91Zy5jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMy41KSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCkNobC5DJFJhbmROW3doaWNoKENobC5DJFRpbWVQPT0iVFAzIiAmIENobC5DJENobF91Zy5jbTI+Mi41KV0gIyJNOF8zMyIgIk04XzMzIiAiTThfMzMiIA0KDQojVFA0DQpnZ3Bsb3Qoc3Vic2V0KENobC5DLCBUaW1lUD09IlRQNCIpLCBhZXMoeD1TZXQsIHk9Q2hsX3VnLmNtMikpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCw0KSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiMjUmVtb3ZlIE91dGxpZXJzIA0KQ2hsLkMubzwtQ2hsLkNbLWMod2hpY2goKENobC5DJFRpbWVQPT0iSU4iICYgQ2hsLkMkQ2hsX3VnLmNtMjwwLjI1KXwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIChDaGwuQyRUaW1lUD09IlRQMyIgJiBDaGwuQyRDaGxfdWcuY20yPjIuNSkpKSxdDQoNCmBgYA0KDQoNCiMjIyMgSGVhdGVkDQpgYGB7cn0NCiMjU3Vic2V0IEhlYXRlZCBUcmVhdG1lbnQgaW4gVGhlcm1hbCBUb2xlcmFuY2UgQXNzYXkNCkNobC5IPC1zdWJzZXQoQ2hsLCBUcmVhdD09IkgiKQ0KDQojSU4NCmdncGxvdChzdWJzZXQoQ2hsLkgsIFRpbWVQPT0iSU4iKSwgYWVzKHg9U2V0LCB5PUNobF91Zy5jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpDaGwuSCRSYW5kTlt3aGljaChDaGwuSCRUaW1lUD09IklOIiAmIENobC5IJENobF91Zy5jbTI+MC43NSldICMiVzJfODgiICJXMl84OCIgIlcyXzg4Ig0KDQojVFAxDQpnZ3Bsb3Qoc3Vic2V0KENobC5ILCBUaW1lUD09IlRQMSIpLCBhZXMoeD1TZXQsIHk9Q2hsX3VnLmNtMikpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCwxKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiNUUDINCmdncGxvdChzdWJzZXQoQ2hsLkgsIFRpbWVQPT0iVFAyIiksIGFlcyh4PVNldCwgeT1DaGxfdWcuY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDEpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQMw0KZ2dwbG90KHN1YnNldChDaGwuSCwgVGltZVA9PSJUUDMiKSwgYWVzKHg9U2V0LCB5PUNobF91Zy5jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMikrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpDaGwuSCRSYW5kTlt3aGljaChDaGwuSCRUaW1lUD09IlRQMyIgJiBDaGwuSCRDaGxfdWcuY20yPjEuNSAmIENobC5IJEdlbm90eXBlPT0iQUMxMCIpXSAjIk04XzExIiAiTThfMTEiDQoNCiNUUDQNCmdncGxvdChzdWJzZXQoQ2hsLkgsIFRpbWVQPT0iVFA0IiksIGFlcyh4PVNldCwgeT1DaGxfdWcuY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDEpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KQ2hsLkgkUmFuZE5bd2hpY2goQ2hsLkgkVGltZVA9PSJUUDQiICYgQ2hsLkgkQ2hsX3VnLmNtMj4wLjUpXSAjIk0xMl82MyIgIk0xMl82MyIgIk0xMl82MyINCg0KIyNSZW1vdmUgT3V0bGllcnMNCkNobC5ILm88LUNobC5IWy1jKHdoaWNoKChDaGwuSCRUaW1lUD09IklOIiAmIENobC5IJENobF91Zy5jbTI+MC43NSkgfA0KKENobC5IJFRpbWVQPT0iVFAzIiAmIENobC5IJENobF91Zy5jbTI+MS41ICYgQ2hsLkgkR2Vub3R5cGU9PSJBQzEwIikgfCANCihDaGwuSCRUaW1lUD09IlRQNCIgJiBDaGwuSCRDaGxfdWcuY20yPjAuNTApKSksXQ0KDQpgYGANCg0KDQojIyMgQWRkIENobG9yb3BoeWxsIHRvIE1haW4gYW5kIFRoZXJtYWwgRGF0YXNldHMNCmBgYHtyfQ0KIyNSZWNvbWJpbmUgQ2xlYW5lZCBDaGxvcm9waHlsbCBkYXRhZnJhbWVzDQpDaGwubzwtcmJpbmQoQ2hsLk0ubywgQ2hsLkMubywgQ2hsLkgubykNCg0KZ2dwbG90KENobC5vLCBhZXMoeD1TZXQsIHk9Q2hsX3VnLmNtMikpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQoNCiMjQXZlcmFnZSBBY3Jvc3MgUmVwbGljYXRlIFJlYWRpbmdzICgiUmVwIiBjb2x1bW46IEEsIEIsIEMpDQpuYW1lcyhDaGwubykNCkNobC5hPC1hZ2dyZWdhdGUoQ2hsLm8kQ2hsX3VnLmNtMiwgbGlzdChDaGwubyRSYW5kTiwgQ2hsLm8kSUQpLCBtZWFuKQ0KbmFtZXMoQ2hsLmEpPC1jKCJSYW5kTiIsICJJRCIsICJDaGxfdWcuY20yIikNCg0KIyNBZGQgVG90YWwgQ2hsb3JvcGh5bGwgdG8gTWFpbiBDb3JhbCBEYXRhIGFuZCBUaGVybWFsIFRvbGVyYW5jZSBEYXRhDQoNCiMjTWVyZ2UgQXZlcmFnZWQgQ2hsb3JvcGh5bGwgRGF0YSB3aXRoIENvcmFsIE1haW4gRGF0YQ0KI01lcmdlcyBieSBSYW5kb20gTnVtYmVyIChSYW5kTikgYW5kIElEIGNvbHVtbnMNCiNSZXRhaW5zIGFsbCBNYWluIHNhbXBsZXMNCm5hbWVzKENobC5hKQ0KQ29yYWxEYXRhPC1tZXJnZShDb3JhbERhdGEsIENobC5hLCBhbGwueD1UUlVFLCBhbGwueT1GQUxTRSkNCg0KIyNNZXJnZSBBdmVyYWdlZCBDaGxvcm9waHlsbCBEYXRhIHdpdGggVGhlcm1hbCBUb2xlcmFuY2UgRGF0YQ0KI01lcmdlcyBieSBSYW5kb20gTnVtYmVyIChSYW5kTikgYW5kIElEIGNvbHVtbnMNCiNSZXRhaW5zIGFsbCBUaGVybWFsIFRvbGVyYW5jZSBBc3NheSBzYW1wbGVzDQojUmV0YWlucyBSYW5kTiwgSUQsIFRpbWVQLCBTaXRlLCBHZW5vdHlwZSwgVHJlYXQsIFRyZWF0bWVudCwgT3JpZywgT3JpZ2luLCBTZXQsIGFuZCBTQV9jbTIgZnJvbSBDb3JhbHNfVGhlcm0NCm5hbWVzKENvcmFsc19UaGVybSkNClRoZXJtRGF0YTwtbWVyZ2UoQ29yYWxzX1RoZXJtWyxjKDE6OSwgMTM6MTQsIDE2KV0sIENobC5hLCBhbGwueD1UUlVFLCBhbGwueT1GQUxTRSkNCg0KYGBgDQoNCg0KIyBTeW1iaW9udHMNCg0KIyMjIENhbGN1bGF0ZSBTeW1iaW9udCBEZW5zaXR5DQpgYGB7cn0NCiMjIyNDYWxjdWxhdGUgRGlsdXRpb24gRmFjdG9ycw0KDQojU2NhbGVzIGZvciAxOjEwIERpbHV0aW9uIFNlbnQgZm9yIEZsb3cgQ3l0b21ldHJ5DQpTeW0kU2VuZF9kZjwtU3ltJFNlbmRJbnB1dFZvbF91bC9TeW0kU2VuZFRvdGFsVm9sX3VsDQoNCiMjU2NhbGVzIGZvciBSZXN1c3BlbmRpbmcgU3ltYmlvbnQgUGVsbGV0IGJhc2VkIG9uIFZvbHVtZSBvZiAwLjAxJSBTRFMgVXNlZA0KU3ltJFJlc3BfZGY8LVN5bSRJbnB1dFZvbF91bC9TeW0kUmVzcFZvbF91bA0KDQojIyMjQ2FsY3VsYXRlIFN5bWJpb250IERlbnNpdHkNCg0KIyNTY2FsZSBGbG93IEN5IENvdW50L3VsIHRvIGFjY291bnQgZm9yIERpbHV0aW9uIEZhY3RvciBhcHBsaWVkIGF0IEZsb3cgQ3kgQ2VudGVyDQpTeW0kQ291bnRfdWxfc2NhbGVkX0ZDX2RmPC1TeW0kQ291bnRfdWwvU3ltJEZDX2RmDQoNCiMjU2NhbGUgRmxvdyBDeSBDb3VudC91bCB0byBhY2NvdW50IGZvciBTZW50IERpbHV0aW9uIEZhY3Rvcg0KU3ltJENvdW50X3VsX3NjYWxlZF9zZW5kX2RmPC1TeW0kQ291bnRfdWxfc2NhbGVkX0ZDX2RmL1N5bSRTZW5kX2RmDQoNCiMjU2NhbGUgRmxvdyBDeSBDb3VudC91bCB0byBhY2NvdW50IGZvciBSZXN1c3BlbnNpb24gRGlsdXRpb24gRmFjdG9yDQpTeW0kQ291bnRfdWxfc2NhbGVkX3Jlc3BfZGY8LVN5bSRDb3VudF91bF9zY2FsZWRfc2VuZF9kZi9TeW0kUmVzcF9kZg0KDQojI01lcmdlIHdpdGggU2FtcGxlIERhdGEgdG8gQ2FsY3VsYXRlIFN5bWJpb250cyBwZXIgU3VyZmFjZSBBcmVhDQojTWVyZ2VzIGJ5IFJhbmRvbSBOdW1iZXIgKFJhbmROKSBjb2x1bW4NCiNBZGRzIG5lY2Vzc2FyeSBTbHVycnkgVm9sdW1lIChWb2xfbWwpIGFuZCBTdXJmYWNlIEFyZWEgKFNBX2NtMikgY29sdW1ucw0KI1JldGFpbnMgU2FtcGxlIE1ldGEgRGF0YSBvbmx5IGZvciBzYW1wbGVzIHdpdGggU3ltYmlvbnQgZGF0YSAoVGhlcm1hbCBBc3NheSBzYW1wbGVzIG9ubHkpDQpTeW08LW1lcmdlKFN5bSwgU2FtcERhdGEsIGFsbC54PVRSVUUsIGFsbC55PUZBTFNFKQ0KDQojI0NhbGN1bGF0ZSBUb3RhbCBTeW1iaW9udCBDb3VudCAoc2NhbGluZyB0byBTbHVycnkgVG90YWwgVm9sdW1lIGluIHVsKQ0KU3ltJENvdW50X3RvdGFsPC1TeW0kQ291bnRfdWxfc2NhbGVkX3Jlc3BfZGYqKFN5bSRWb2xfbWwqMTAwMCkNCg0KIyNDYWxjdWxhdGUgU3ltYmlvbnRzIHBlciBTdXJmYWNlIEFyZWENClN5bSRTeW1fY20yPC1TeW0kQ291bnRfdG90YWwvU3ltJFNBX2NtMg0KDQojI1NjYWxlIHRvIFN5bWIgKiAxMF42IC8gY21eMg0KU3ltJFN5bTEwLjZfY20yPC1TeW0kU3ltX2NtMi8xMF42DQoNCiMjSW5pdGlhbCBWaXN1YWwgQ2hlY2sNCmdncGxvdChTeW0sIGFlcyh4PVNldCwgeT1TeW0xMC42X2NtMikpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpgYGANCg0KDQojIyMgQ2hlY2sgZm9yIE91dGxpZXJzDQpDaGVjayBmb3IgT3V0bGllcnMgYnkgVHJlYXRtZW50IGFuZCBUaW1lcG9pbnQsIGdyb3VwZWQgYnkgc2FtcGxlIHNldC4gUmVtb3Zpbmcgb3V0bGllcnMgb2YgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgYmVmb3JlIGF2ZXJhZ2luZyBhY3Jvc3MgdGVjaG5pY2FsIHJlcGxpYXRlcy4gDQoNCiMjIyMgQ29udHJvbA0KYGBge3J9DQojI1N1YnNldCBDb250cm9sIFRyZWF0bWVudCBpbiBUaGVybWFsIFRvbGVyYW5jZSBBc3NheQ0KU3ltLkM8LXN1YnNldChTeW0sIFRyZWF0PT0iQyIpDQpTeW0uQzwtU3ltLkNbLWMod2hpY2goaXMubmEoU3ltLkMkU3ltMTAuNl9jbTIpKSksXQ0KDQojSU4NCmdncGxvdChzdWJzZXQoU3ltLkMsIFRpbWVQPT0iSU4iKSwgYWVzKHg9U2V0LCB5PVN5bTEwLjZfY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQMQ0KZ2dwbG90KHN1YnNldChTeW0uQywgVGltZVA9PSJUUDEiKSwgYWVzKHg9U2V0LCB5PVN5bTEwLjZfY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQMg0KZ2dwbG90KHN1YnNldChTeW0uQywgVGltZVA9PSJUUDIiKSwgYWVzKHg9U2V0LCB5PVN5bTEwLjZfY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQMw0KZ2dwbG90KHN1YnNldChTeW0uQywgVGltZVA9PSJUUDMiKSwgYWVzKHg9U2V0LCB5PVN5bTEwLjZfY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQNA0KZ2dwbG90KHN1YnNldChTeW0uQywgVGltZVA9PSJUUDQiKSwgYWVzKHg9U2V0LCB5PVN5bTEwLjZfY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KYGBgDQoNCg0KIyMjIyBIZWF0ZWQNCmBgYHtyfQ0KIyNTdWJzZXQgSGVhdGVkIFRyZWF0bWVudCBpbiBUaGVybWFsIFRvbGVyYW5jZSBBc3NheQ0KU3ltLkg8LXN1YnNldChTeW0sIFRyZWF0PT0iSCIpDQoNCiNJTg0KZ2dwbG90KHN1YnNldChTeW0uSCwgVGltZVA9PSJJTiIpLCBhZXMoeD1TZXQsIHk9U3ltMTAuNl9jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojVFAxDQpnZ3Bsb3Qoc3Vic2V0KFN5bS5ILCBUaW1lUD09IlRQMSIpLCBhZXMoeD1TZXQsIHk9U3ltMTAuNl9jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpTeW0uSCRSYW5kTlt3aGljaChTeW0uSCRUaW1lUD09IlRQMSIgJiBTeW0uSCRTeW0xMC42X2NtMj4wLjc1KV0gIyJNMV83MyIgIk0xXzczIg0KDQojVFAyDQpnZ3Bsb3Qoc3Vic2V0KFN5bS5ILCBUaW1lUD09IlRQMiIpLCBhZXMoeD1TZXQsIHk9U3ltMTAuNl9jbTIpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAsMS41KSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNClN5bS5IJFJhbmROW3doaWNoKFN5bS5IJFRpbWVQPT0iVFAyIiAmIFN5bS5IJFN5bTEwLjZfY20yPjAuNzUpXSAjIk00XzYxIiAiTTRfODUiDQoNCiNUUDMNCmdncGxvdChzdWJzZXQoU3ltLkgsIFRpbWVQPT0iVFAzIiksIGFlcyh4PVNldCwgeT1TeW0xMC42X2NtMikpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMCwyLjEpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KU3ltLkgkUmFuZE5bd2hpY2goU3ltLkgkVGltZVA9PSJUUDMiICYgU3ltLkgkU3ltMTAuNl9jbTI+MS44KV0gIyJNOF80MiINCg0KI1RQNA0KZ2dwbG90KHN1YnNldChTeW0uSCwgVGltZVA9PSJUUDQiKSwgYWVzKHg9U2V0LCB5PVN5bTEwLjZfY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLDEpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KIyNSZW1vdmUgT3V0bGllcnMNClN5bS5ILm88LVN5bS5IWy1jKHdoaWNoKChTeW0uSCRUaW1lUD09IlRQMSIgJiBTeW0uSCRTeW0xMC42X2NtMj4wLjc1KSB8IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAoU3ltLkgkVGltZVA9PSJUUDIiICYgU3ltLkgkU3ltMTAuNl9jbTI+MC43NSkgfA0KICAgICAgICAgICAgICAgICAgICAgICAgICAoU3ltLkgkVGltZVA9PSJUUDMiICYgU3ltLkgkU3ltMTAuNl9jbTI+MS44KSkpLF0NCg0KYGBgDQoNCg0KIyMjIEFkZCBTeW1iaW9udHMgdG8gVGhlcm1hbCBEYXRhDQpgYGB7cn0NCiMjUmVjb21iaW5lIENsZWFuZWQgU3ltYmlvbnRzIGRhdGFmcmFtZXMNClN5bS5vPC1yYmluZChTeW0uQywgU3ltLkgubykNCg0KIyNWaXN1YWwgQ2hlY2sNCmdncGxvdChTeW0ubywgYWVzKHg9U2V0LCB5PVN5bTEwLjZfY20yKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNCiMjQXZlcmFnZSBBY3Jvc3MgUmVwbGljYXRlIFJlYWRpbmdzICgiUmVwIiBjb2x1bW46IEEsIEIsIEMpDQpuYW1lcyhTeW0ubykNClN5bS5hPC1hZ2dyZWdhdGUoU3ltLm8kU3ltMTAuNl9jbTIsIGxpc3QoU3ltLm8kUmFuZE4sIFN5bS5vJElEKSwgbWVhbikNCm5hbWVzKFN5bS5hKTwtYygiUmFuZE4iLCAiSUQiLCAiU3ltMTAuNl9jbTIiKQ0KDQojI0FkZCBTeW1iaW9udCBEZW5zaXR5IHRvIFRoZXJtYWwgVG9sZXJhbmNlIERhdGENCg0KIyNNZXJnZSBBdmVyYWdlZCBTeW1iaW9udCBEYXRhIHdpdGggVGhlcm1hbCBUb2xlcmFuY2UgRGF0YQ0KI01lcmdlcyBieSBSYW5kb20gTnVtYmVyIChSYW5kTikgYW5kIElEIGNvbHVtbnMNCiNSZXRhaW5zIGFsbCBUaGVybWFsIFRvbGVyYW5jZSBBc3NheSBzYW1wbGVzDQpuYW1lcyhUaGVybURhdGEpDQpUaGVybURhdGE8LW1lcmdlKFRoZXJtRGF0YSwgU3ltLmEsIGFsbC54PVRSVUUsIGFsbC55PUZBTFNFKQ0KDQpgYGANCg0KDQojIEZ2L0ZtDQoNCiMjIyBPcmdhbml6ZSBEYXRhDQpgYGB7cn0NCiMjTWVyZ2UgUEFNIE1ldGEgRGF0YSB3aXRoIFBBTSBEYXRhDQojTWVyZ2VzIGJ5IE1lbW9yeSBOdW1iZXIgKE1lbW9yeSkgY29sdW1uDQojUmV0YWlucyBQQU0gRGF0YSBvbmx5IGZvciByZWxldmFudCBtZWFzdXJlbWVudHMgd2l0aCBNZXRhIERhdGEgDQpQQU08LW1lcmdlKFBBTV9NZXRhLCBQQU0sIGFsbC54PVRSVUUsIGFsbC55PUZBTFNFKQ0KDQpQQU08LVBBTVstYyh3aGljaChpcy5uYShQQU0kRnZfRm0pKSksXQ0KDQojI01lcmdlIFBBTSBEYXRhIHdpdGggU2FtcGxlIERhdGENCiNNZXJnZXMgYnkgSUQgY29sdW1uDQojUmV0YWlucyBTYW1wbGUgTWV0YSBEYXRhIG9ubHkgZm9yIHNhbXBsZXMgd2l0aCBGdi9GbSBkYXRhIChUaGVybWFsIEFzc2F5IHNhbXBsZXMgb25seSkNClBBTTwtbWVyZ2UoUEFNLCBTYW1wRGF0YSwgYWxsLng9VFJVRSwgYWxsLnk9RkFMU0UpDQoNCiMjSW5pdGlhbCBWaXN1YWwgQ2hlY2sNCmdncGxvdChQQU0sIGFlcyh4PVNldCwgeT1Gdl9GbSkpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpgYGANCg0KDQojIyMgQ2hlY2sgZm9yIE91dGxpZXJzDQpDaGVjayBmb3IgT3V0bGllcnMgYnkgVHJlYXRtZW50IGFuZCBUaW1lcG9pbnQsIGdyb3VwZWQgYnkgc2FtcGxlIHNldC4gUmVtb3Zpbmcgb3V0bGllcnMgb2YgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgYmVmb3JlIGF2ZXJhZ2luZyBhY3Jvc3MgdGVjaG5pY2FsIHJlcGxpYXRlcy4gDQoNCiMjIyMgQ29udHJvbA0KYGBge3J9DQojI1N1YnNldCBDb250cm9sIFRyZWF0bWVudCBpbiBUaGVybWFsIFRvbGVyYW5jZSBBc3NheQ0KUEFNLkM8LXN1YnNldChQQU0sIFRyZWF0PT0iQyIpDQoNCiNJTg0KZ2dwbG90KHN1YnNldChQQU0uQywgVGltZVA9PSJJTiIpLCBhZXMoeD1TZXQsIHk9RnZfRm0pKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAuNDUsMC43NSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpQQU0uQyRSYW5kTlt3aGljaChQQU0uQyRUaW1lUD09IklOIiAmIFBBTS5DJEZ2X0ZtPDAuNSldICMgIlcyXzkzIiANCg0KI1RQMQ0KZ2dwbG90KHN1YnNldChQQU0uQywgVGltZVA9PSJUUDEiKSwgYWVzKHg9U2V0LCB5PUZ2X0ZtKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLjQ1LDAuNzUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KI1RQMg0KZ2dwbG90KHN1YnNldChQQU0uQywgVGltZVA9PSJUUDIiKSwgYWVzKHg9U2V0LCB5PUZ2X0ZtKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLjQ1LDAuNzUpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KUEFNLkMkUmFuZE5bd2hpY2goUEFNLkMkVGltZVA9PSJUUDIiICYgUEFNLkMkRnZfRm08MC41MyldICMgIk00XzkxIg0KDQojVFAzDQpnZ3Bsb3Qoc3Vic2V0KFBBTS5DLCBUaW1lUD09IlRQMyIpLCBhZXMoeD1TZXQsIHk9RnZfRm0pKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAuNDUsMC43NSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojVFA0DQpnZ3Bsb3Qoc3Vic2V0KFBBTS5DLCBUaW1lUD09IlRQNCIpLCBhZXMoeD1TZXQsIHk9RnZfRm0pKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAuNDUsMC43NSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQojI1JlbW92ZSBPdXRsaWVycw0KUEFNLkMubzwtUEFNLkNbLWMod2hpY2goKFBBTS5DJFRpbWVQPT0iSU4iICYgUEFNLkMkRnZfRm08MC41KSB8IChQQU0uQyRUaW1lUD09IlRQMiIgJiBQQU0uQyRGdl9GbTwwLjUzKSkpLF0NCg0KYGBgDQoNCg0KDQoNCiMjIyMgSGVhdGVkDQpgYGB7cn0NCiMjU3Vic2V0IEhlYXRlZCBUcmVhdG1lbnQgaW4gVGhlcm1hbCBUb2xlcmFuY2UgQXNzYXkNClBBTS5IPC1zdWJzZXQoUEFNLCBUcmVhdD09IkgiKQ0KDQojSU4NCmdncGxvdChzdWJzZXQoUEFNLkgsIFRpbWVQPT0iSU4iKSwgYWVzKHg9U2V0LCB5PUZ2X0ZtKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLjI1LDAuNykrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpQQU0uSCRSYW5kTlt3aGljaChQQU0uSCRUaW1lUD09IklOIiAmIFBBTS5IJEZ2X0ZtPDAuNSAmICBQQU0uSCRTaXRlPT0iU1MiKV0gIyAiVzJfOTQiICJXMl85NCINCg0KDQojVFAxDQpnZ3Bsb3Qoc3Vic2V0KFBBTS5ILCBUaW1lUD09IlRQMSIpLCBhZXMoeD1TZXQsIHk9RnZfRm0pKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB5bGltKDAuMjUsMC43KSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpDQoNClBBTS5IJFJhbmROW3doaWNoKFBBTS5IJFRpbWVQPT0iVFAxIiAmIFBBTS5IJEZ2X0ZtPDAuMzUpXSAjICJNMV84NiINCg0KI1RQMg0KZ2dwbG90KHN1YnNldChQQU0uSCwgVGltZVA9PSJUUDIiKSwgYWVzKHg9U2V0LCB5PUZ2X0ZtKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLjI1LDAuNykrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpQQU0uSCRSYW5kTlt3aGljaChQQU0uSCRUaW1lUD09IlRQMiIgJiBQQU0uSCRGdl9GbTwwLjM1ICYgIFBBTS5IJFNpdGU9PSJTUyIpXSAjICJNNF84NCINCg0KI1RQMw0KZ2dwbG90KHN1YnNldChQQU0uSCwgVGltZVA9PSJUUDMiKSwgYWVzKHg9U2V0LCB5PUZ2X0ZtKSkgKyANCiAgZ2VvbV9ib3hwbG90KGFscGhhPTAuNSwgc2hhcGU9Miwgb3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpKSsNCiAgeWxpbSgwLjI1LDAuNykrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpQQU0uSCRSYW5kTlt3aGljaChQQU0uSCRUaW1lUD09IlRQMyIgJiBQQU0uSCRGdl9GbTwwLjQ1KV0gIyAiTThfODMiDQoNCiNUUDQNCmdncGxvdChzdWJzZXQoUEFNLkgsIFRpbWVQPT0iVFA0IiksIGFlcyh4PVNldCwgeT1Gdl9GbSkpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHlsaW0oMC4yLDAuNykrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQoNCiMjUmVtb3ZlIE91dGxpZXJzIA0KUEFNLkgubzwtUEFNLkhbLWMod2hpY2goKFBBTS5IJFRpbWVQPT0iSU4iICYgUEFNLkgkRnZfRm08MC41ICYgIFBBTS5IJFNpdGU9PSJTUyIpIHwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIChQQU0uSCRUaW1lUD09IlRQMSIgJiBQQU0uSCRGdl9GbTwwLjM1KXwNCiAgICAgICAgICAgICAgKFBBTS5IJFRpbWVQPT0iVFAyIiAmIFBBTS5IJEZ2X0ZtPDAuMzUgJiAgUEFNLkgkU2l0ZT09IlNTIikgfA0KICAgICAgICAgICAgICAgIChQQU0uSCRUaW1lUD09IlRQMyIgJiBQQU0uSCRGdl9GbTwwLjQ1KSkpLF0NCg0KYGBgDQoNCiMjIyBBZGQgRnYvRm0gdG8gVGhlcm1hbCBEYXRhDQpgYGB7cn0NCiMjUmVjb21iaW5lIENsZWFuZWQgUEFNIGRhdGFmcmFtZXMNClBBTS5vPC1yYmluZChQQU0uQy5vLCBQQU0uSC5vKQ0KDQpnZ3Bsb3QoUEFNLm8sIGFlcyh4PVNldCwgeT1Gdl9GbSkpICsgDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUsIHNoYXBlPTIsIG91dGxpZXIuc2hhcGUgPSBOQSkrDQogIGdlb21faml0dGVyKHNoYXBlPTE2LCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIoMC4xKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQoNCiMjQXZlcmFnZSBBY3Jvc3MgUmVwbGljYXRlIFJlYWRpbmdzICgiUmVwIiBjb2x1bW46IEEsIEIsIEMpDQpuYW1lcyhQQU0ubykNClBBTS5hPC1hZ2dyZWdhdGUoUEFNLm8kRnZfRm0sIGxpc3QoUEFNLm8kSUQpLCBtZWFuKQ0KbmFtZXMoUEFNLmEpPC1jKCJJRCIsICJGdl9GbSIpDQoNCiMjQWRkIEZ2L0ZtIHRvIFRoZXJtYWwgVG9sZXJhbmNlIERhdGENCg0KIyNNZXJnZSBBdmVyYWdlZCBGdi9GbSBEYXRhIHdpdGggVGhlcm1hbCBUb2xlcmFuY2UgRGF0YQ0KI01lcmdlcyBieSBJRCBjb2x1bW4NCiNSZXRhaW5zIGFsbCBUaGVybWFsIFRvbGVyYW5jZSBBc3NheSBzYW1wbGVzDQpuYW1lcyhUaGVybURhdGEpDQpUaGVybURhdGE8LW1lcmdlKFRoZXJtRGF0YSwgUEFNLmEsIGFsbC54PVRSVUUsIGFsbC55PUZBTFNFKQ0KDQpgYGANCg0KDQojIFdyaXRlIE91dCBEYXRhc2V0cw0KYGBge3J9DQojI01haW4gQ29yYWwgRGF0YQ0Kd3JpdGUuY3N2KENvcmFsRGF0YSwgIk91dHB1dHMvQ29yYWxEYXRhLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkNCg0KIyNUaGVybWFsIFRvbGVyYW5jZSBBc3NheQ0Kd3JpdGUuY3N2KFRoZXJtRGF0YSwgIk91dHB1dHMvVGhlcm1EYXRhLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkNCg0KYGBgDQoNCg==